VIM3/VIM3L: update NPU driver to 6.4.0.3
authorNick Xie <nick@khadas.com>
Wed, 8 Apr 2020 10:36:29 +0000 (18:36 +0800)
committerNick Xie <nick@khadas.com>
Fri, 24 Apr 2020 09:41:39 +0000 (17:41 +0800)
commit 6b11429e83c1d8a15045b03c9189142b6a79157a
Author: cancan.chang <cancan.chang@amlogic.com>
Date:   Fri Oct 18 15:26:03 2019 +0800

    npu: release ddk 6.4.0.3 [1/1]

    PD#SWPL-15561

    Problem:
    no

    Solution:
    release new driver

    Verify:
    w400 sm1 ae400

    Change-Id: I0a972283e7757c55ed2f56fe124a42b53f08f84a
Signed-off-by: cancan.chang <cancan.chang@amlogic.com>
Signed-off-by: Nick Xie <nick@khadas.com>
94 files changed:
arch/arm64/boot/dts/amlogic/mesong12b.dtsi
arch/arm64/boot/dts/amlogic/mesonsm1.dtsi
drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_interface.h [new file with mode: 0644]
drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_kernel_profile.h [new file with mode: 0644]
drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_lib_link.h [new file with mode: 0644]
drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_program_profile.h [new file with mode: 0644]
drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_shader_priv_mapping.h [new file with mode: 0644]
drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_shader_profile.h [new file with mode: 0644]
drivers/amlogic/npu/inc/gc_feature_database.h
drivers/amlogic/npu/inc/gc_hal.h
drivers/amlogic/npu/inc/gc_hal_base.h
drivers/amlogic/npu/inc/gc_hal_cl.h
drivers/amlogic/npu/inc/gc_hal_debug_zones.h [new file with mode: 0644]
drivers/amlogic/npu/inc/gc_hal_driver.h
drivers/amlogic/npu/inc/gc_hal_engine.h
drivers/amlogic/npu/inc/gc_hal_enum.h
drivers/amlogic/npu/inc/gc_hal_metadata.h [new file with mode: 0644]
drivers/amlogic/npu/inc/gc_hal_options.h
drivers/amlogic/npu/inc/gc_hal_priv.h
drivers/amlogic/npu/inc/gc_hal_profiler.h
drivers/amlogic/npu/inc/gc_hal_raster.h
drivers/amlogic/npu/inc/gc_hal_types.h
drivers/amlogic/npu/inc/gc_hal_version.h
drivers/amlogic/npu/inc/gc_hal_vg.h
drivers/amlogic/npu/inc/gc_hal_vx.h
drivers/amlogic/npu/inc/gc_vsc_precomp.h [new file with mode: 0644]
drivers/amlogic/npu/inc/old_impl/gc_vsc_old_drvi_interface.h [new file with mode: 0644]
drivers/amlogic/npu/inc/old_impl/gc_vsc_old_gcsl.h [new file with mode: 0644]
drivers/amlogic/npu/kernel/Android.mk
drivers/amlogic/npu/kernel/arch/gc_hal_kernel_context.c
drivers/amlogic/npu/kernel/arch/gc_hal_kernel_context.h
drivers/amlogic/npu/kernel/arch/gc_hal_kernel_hardware.c
drivers/amlogic/npu/kernel/arch/gc_hal_kernel_hardware.h
drivers/amlogic/npu/kernel/arch/gc_hal_kernel_hardware_async_fe.c
drivers/amlogic/npu/kernel/arch/gc_hal_kernel_hardware_mc_fe.c
drivers/amlogic/npu/kernel/arch/gc_hal_kernel_hardware_waitlink_fe.c
drivers/amlogic/npu/kernel/gc_hal_kernel.c
drivers/amlogic/npu/kernel/gc_hal_kernel.h
drivers/amlogic/npu/kernel/gc_hal_kernel_command.c
drivers/amlogic/npu/kernel/gc_hal_kernel_db.c
drivers/amlogic/npu/kernel/gc_hal_kernel_debug.c
drivers/amlogic/npu/kernel/gc_hal_kernel_event.c
drivers/amlogic/npu/kernel/gc_hal_kernel_heap.c
drivers/amlogic/npu/kernel/gc_hal_kernel_mmu.c
drivers/amlogic/npu/kernel/gc_hal_kernel_video_memory.c
drivers/amlogic/npu/kernel/inc/gc_feature_database.h
drivers/amlogic/npu/kernel/inc/gc_hal.h
drivers/amlogic/npu/kernel/inc/gc_hal_base.h
drivers/amlogic/npu/kernel/inc/gc_hal_debug_zones.h [new file with mode: 0644]
drivers/amlogic/npu/kernel/inc/gc_hal_driver.h
drivers/amlogic/npu/kernel/inc/gc_hal_drm.h
drivers/amlogic/npu/kernel/inc/gc_hal_engine.h
drivers/amlogic/npu/kernel/inc/gc_hal_enum.h
drivers/amlogic/npu/kernel/inc/gc_hal_kernel_buffer.h
drivers/amlogic/npu/kernel/inc/gc_hal_metadata.h [new file with mode: 0644]
drivers/amlogic/npu/kernel/inc/gc_hal_options.h
drivers/amlogic/npu/kernel/inc/gc_hal_profiler.h
drivers/amlogic/npu/kernel/inc/gc_hal_raster.h
drivers/amlogic/npu/kernel/inc/gc_hal_types.h
drivers/amlogic/npu/kernel/inc/gc_hal_version.h
drivers/amlogic/npu/kernel/inc/gc_hal_vg.h
drivers/amlogic/npu/os/libGAL.def.mak
drivers/amlogic/npu/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c
drivers/amlogic/npu/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c
drivers/amlogic/npu/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c
drivers/amlogic/npu/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c
drivers/amlogic/npu/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_debug.h
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_device.c
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_device.h
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_driver.c
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_drm.c
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_linux.c
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_linux.h
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_os.c
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_os.h
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_platform.h
drivers/amlogic/npu/os/linux/kernel/gc_hal_kernel_sync.c
drivers/amlogic/npu/os/linux/kernel/platform/amlogic/gc_hal_kernel_platform_amlogic.c
drivers/amlogic/npu/os/linux/kernel/platform/amlogic/gc_hal_kernel_platform_amlogic.config
drivers/amlogic/npu/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.c
drivers/amlogic/npu/os/linux/user/Android.mk
drivers/amlogic/npu/os/linux/user/bin_r/gc_hal_user_debug.d
drivers/amlogic/npu/os/linux/user/bin_r/gc_hal_user_math.d
drivers/amlogic/npu/os/linux/user/bin_r/gc_hal_user_os.d
drivers/amlogic/npu/os/linux/user/bin_r/gc_hal_user_platform_default.d
drivers/amlogic/npu/os/linux/user/gc_hal_user_debug.c
drivers/amlogic/npu/os/linux/user/gc_hal_user_os.c
drivers/amlogic/npu/os/linux/user/makefile.linux
drivers/amlogic/npu/os/vxworks/user/gc_hal_user_os.c [deleted file]
drivers/amlogic/npu/security/Android.mk
drivers/amlogic/npu/security_v1/gc_hal_ta_hardware.c
drivers/amlogic/npu/security_v1/gc_hal_ta_mmu.c
drivers/amlogic/npu/security_v1/os/emulator/gc_hal_ta_emulator.c

index afd695b9bbd379592160a3f788bd9c2519bfdf9a..3928cd4e10aa8e62326532c0e2bff8adc14a7669 100644 (file)
                        >;
                reg-names = "NN_REG","NN_SRAM","NN_MEM0",
                        "NN_MEM1","NN_RESET","NN_CLK";
+               nn_power_version = <2>;
                nn_efuse = <0xff63003c 0x20>;
        };
 
index f06069302d5c07e69032db70763628f21fcb7c73..1493f6a5258a40b11416297752ed3f6085d51dab 100644 (file)
                interrupts = <0 186 4>;
                interrupt-names = "galcore";
                reg = <0x0 0xff100000 0x0 0x800
-                       /*reg base value:0xff100000 */
                        0x0 0xff000000 0x0 0x400000
-                       /*Sram bse value:0xff000000*/
                        0x0 0xff63c118 0x0 0x0
                        0x0 0xff63c11c 0x0 0x0
-                       /*0xff63c118,0xff63c11c :nanoq mem regs*/
                        0x0 0xffd01088 0x0 0x0
-                       /*0xffd01088:reset reg*/
+                       0x0 0xff63c1c8 0x0 0x0
                        >;
+               reg-names = "NN_REG","NN_SRAM","NN_MEM0",
+                       "NN_MEM1","NN_RESET","NN_CLK";
+               nn_power_version = <3>;
                nn_efuse = <0xff63003c 0x20>;
        };
        aocec: aocec {
diff --git a/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_interface.h b/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_interface.h
new file mode 100644 (file)
index 0000000..01b29f8
--- /dev/null
@@ -0,0 +1,1393 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+/*
+** Main interface header that outside world uses
+*/
+
+#ifndef __gc_vsc_drvi_interface_h_
+#define __gc_vsc_drvi_interface_h_
+
+#include "gc_vsc_precomp.h"
+
+/* It will be fully removed after VIR totally replaces of gcSL */
+#include "old_impl/gc_vsc_old_drvi_interface.h"
+
+/******************************* VIR SHADER BINARY FILE VERSION ******************/
+/* current version */
+/* 0.0.1.4 add chipModel and ChipRevision, Nov. 30, 2017 */
+/* 0.0.1.6 add VIR_OP_CLAMPCOORD, Feb. 2, 2018 */
+/* 0.0.1.7 remove VG from shader flags, Mar. 1, 2018 */
+/* 0.0.1.8 add component for VIR_Layout, Mar. 1, 2018 */
+/* 0.0.1.9 save fixedTypeId for output variable, Mar. 5, 2018 */
+/* 0.0.1.10 save extension flags for VIR_Shader, Mar. 6, 2018 */
+/* 0.0.1.11 implement lib function nmin, nmax and nclamp, Mar. 12, 2018 */
+/* 0.0.1.12 save the funcId for separateImage/separateSampler, Mar. 13, 2018 */
+/* 0.0.1.13 save the function sym for a local symbol, Mar. 14, 2018 */
+/* 0.0.1.14 add one more flag for VIR_Function, Mar. 21, 2018 */
+/* 0.0.1.15 add the parameter "lod" for image_fetch_samplerBuffer, Mar. 30, 2018 */
+/* 0.0.1.16 add a flag in VIR_Uniform, Apr. 2, 2018 */
+/* 0.0.1.17 save more memoryAccessFlag, Apr. 19, 2018 */
+/* 0.0.1.18 change image_fetch_gsamplerBuffer prototype, Aug. 28, 2018 */
+/* 0.0.1.19 add atomic patch library function */
+/* 0.0.1.20 add imageFetch/texelBufferToImage, Nov. 2, 2018 */
+/* 0.0.1.21 save the UBO symbol ID for the baseAddress, Nov. 8, 2018 */
+/* 0.0.1.22 modify _viv_atan2_float() to comform to CL spec on 11/20/2018 */
+/* 0.0.1.23 using HALTI5 trig functions for all cases (not just conformance) on 12/3/2018 */
+/* 0.0.1.24 save the kernel function name ID on 12/24/2018 */
+/* 0.0.1.25 add image_query_size lib functions for samplerMS on 12/27/2018 */
+/* 0.0.1.26 remove some enumerations for VIR_ShaderFlags on 01/02/2019 */
+/* 0.0.1.27 Add VIR_ModifierOrder in VIR_Operand on 01/03/2019 */
+/* 0.0.1.28 Add magicNumber on shaderIOBuffer 01/08/2019 */
+/* 0.0.1.29 Add some new opcodes 04/01/2019 */
+/* 0.0.1.30 Add some flags in VIR_Shader and hints 04/17/2019 */
+/* 0.0.1.31 Save module processes in VIR_Shader and hints 05/24/2019 */
+/* 0.0.1.32 Add extension flag in VIR_Symbol 05/27/2019 */
+/* 0.0.1.33 Add a new opcode LOGICAL_RSHIFT 05/28/2019 */
+/* 0.0.1.34 Add WorkGroupSizeFactor in VIR_ComputeLayout on 07/18/2019 */
+#define gcdVIR_SHADER_BINARY_FILE_VERSION gcmCC(SHADER_64BITMODE, 0, 1, 34)
+#define gcdVIR_PROGRAM_BINARY_FILE_VERSION gcmCC(SHADER_64BITMODE, 0, 1, 34)
+
+#if !defined(gcdTARGETHOST_BIGENDIAN)
+#define gcdTARGETHOST_BIGENDIAN 0  /* default host little endian, to change the
+                                    * host to big endian, build with -DgcdHOST_BIGENDIAN=1 */
+#endif
+#define gcdTARGETDEVICE_BIGENDIAN 0  /* device always little endian */
+
+#define gcdSUPPORT_OCL_1_2          1
+#define TREAT_ES20_INTEGER_AS_FLOAT 0
+#define __USE_IMAGE_LOAD_TO_ACCESS_SAMPLER_BUFFER__ 1
+
+BEGIN_EXTERN_C()
+
+/* Copy from _VIR_PRIMITIVETYPEID. */
+typedef enum _VSC_SHADER_DATA_TYPE
+{
+    VSC_SHADER_DATA_TYPE_UNKNOWN            = 0,
+    VSC_SHADER_DATA_TYPE_VOID,
+    /* scalar types */
+    /* types can be mapped to equivalent machine type directly */
+    VSC_SHADER_DATA_TYPE_FLOAT32,
+    VSC_SHADER_DATA_TYPE_FLOAT16,
+    VSC_SHADER_DATA_TYPE_INT32,
+    VSC_SHADER_DATA_TYPE_INT16,
+    VSC_SHADER_DATA_TYPE_INT8,
+    VSC_SHADER_DATA_TYPE_UINT32,
+    VSC_SHADER_DATA_TYPE_UINT16,
+    VSC_SHADER_DATA_TYPE_UINT8,
+    VSC_SHADER_DATA_TYPE_SNORM16,
+    VSC_SHADER_DATA_TYPE_SNORM8,
+    VSC_SHADER_DATA_TYPE_UNORM16,
+    VSC_SHADER_DATA_TYPE_UNORM8,
+
+    /* scalar types not supported by HW */
+    VSC_SHADER_DATA_TYPE_INT64,
+    VSC_SHADER_DATA_TYPE_UINT64,
+    VSC_SHADER_DATA_TYPE_FLOAT64,
+    VSC_SHADER_DATA_TYPE_BOOLEAN,
+
+    /* vector types */
+    /* openCL support vector 8, 16 for all scalar types: int16, int8, etc */
+    VSC_SHADER_DATA_TYPE_FLOAT_X2,
+    VSC_SHADER_DATA_TYPE_FLOAT_X3,
+    VSC_SHADER_DATA_TYPE_FLOAT_X4,
+    VSC_SHADER_DATA_TYPE_FLOAT_X8,
+    VSC_SHADER_DATA_TYPE_FLOAT_X16,
+    VSC_SHADER_DATA_TYPE_FLOAT_X32,
+
+    VSC_SHADER_DATA_TYPE_FLOAT16_X2,
+    VSC_SHADER_DATA_TYPE_FLOAT16_X3,
+    VSC_SHADER_DATA_TYPE_FLOAT16_X4,
+    VSC_SHADER_DATA_TYPE_FLOAT16_X8,
+    VSC_SHADER_DATA_TYPE_FLOAT16_X16,
+    VSC_SHADER_DATA_TYPE_FLOAT16_X32,
+
+    VSC_SHADER_DATA_TYPE_FLOAT64_X2,
+    VSC_SHADER_DATA_TYPE_FLOAT64_X3,
+    VSC_SHADER_DATA_TYPE_FLOAT64_X4,
+    VSC_SHADER_DATA_TYPE_FLOAT64_X8,
+    VSC_SHADER_DATA_TYPE_FLOAT64_X16,
+    VSC_SHADER_DATA_TYPE_FLOAT64_X32,
+
+    VSC_SHADER_DATA_TYPE_BOOLEAN_X2,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_X3,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_X4,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_X8,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_X16,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_X32,
+
+    VSC_SHADER_DATA_TYPE_INTEGER_X2,
+    VSC_SHADER_DATA_TYPE_INTEGER_X3,
+    VSC_SHADER_DATA_TYPE_INTEGER_X4,
+    VSC_SHADER_DATA_TYPE_INTEGER_X8,
+    VSC_SHADER_DATA_TYPE_INTEGER_X16,
+    VSC_SHADER_DATA_TYPE_INTEGER_X32,
+
+    VSC_SHADER_DATA_TYPE_UINT_X2,
+    VSC_SHADER_DATA_TYPE_UINT_X3,
+    VSC_SHADER_DATA_TYPE_UINT_X4,
+    VSC_SHADER_DATA_TYPE_UINT_X8,
+    VSC_SHADER_DATA_TYPE_UINT_X16,
+    VSC_SHADER_DATA_TYPE_UINT_X32,
+
+    /* uchar vectors */
+    VSC_SHADER_DATA_TYPE_UINT8_X2,
+    VSC_SHADER_DATA_TYPE_UINT8_X3,
+    VSC_SHADER_DATA_TYPE_UINT8_X4,
+    VSC_SHADER_DATA_TYPE_UINT8_X8,
+    VSC_SHADER_DATA_TYPE_UINT8_X16,
+    VSC_SHADER_DATA_TYPE_UINT8_X32,
+
+    /* char vectors */
+    VSC_SHADER_DATA_TYPE_INT8_X2,
+    VSC_SHADER_DATA_TYPE_INT8_X3,
+    VSC_SHADER_DATA_TYPE_INT8_X4,
+    VSC_SHADER_DATA_TYPE_INT8_X8,
+    VSC_SHADER_DATA_TYPE_INT8_X16,
+    VSC_SHADER_DATA_TYPE_INT8_X32,
+
+    /* ushort vectors */
+    VSC_SHADER_DATA_TYPE_UINT16_X2,
+    VSC_SHADER_DATA_TYPE_UINT16_X3,
+    VSC_SHADER_DATA_TYPE_UINT16_X4,
+    VSC_SHADER_DATA_TYPE_UINT16_X8,
+    VSC_SHADER_DATA_TYPE_UINT16_X16,
+    VSC_SHADER_DATA_TYPE_UINT16_X32,
+
+    /* short vectors */
+    VSC_SHADER_DATA_TYPE_INT16_X2,
+    VSC_SHADER_DATA_TYPE_INT16_X3,
+    VSC_SHADER_DATA_TYPE_INT16_X4,
+    VSC_SHADER_DATA_TYPE_INT16_X8,
+    VSC_SHADER_DATA_TYPE_INT16_X16,
+    VSC_SHADER_DATA_TYPE_INT16_X32,
+
+    /* uint64 vectors */
+    VSC_SHADER_DATA_TYPE_UINT64_X2,
+    VSC_SHADER_DATA_TYPE_UINT64_X3,
+    VSC_SHADER_DATA_TYPE_UINT64_X4,
+    VSC_SHADER_DATA_TYPE_UINT64_X8,
+    VSC_SHADER_DATA_TYPE_UINT64_X16,
+    VSC_SHADER_DATA_TYPE_UINT64_X32,
+
+    /* int64 vectors */
+    VSC_SHADER_DATA_TYPE_INT64_X2,
+    VSC_SHADER_DATA_TYPE_INT64_X3,
+    VSC_SHADER_DATA_TYPE_INT64_X4,
+    VSC_SHADER_DATA_TYPE_INT64_X8,
+    VSC_SHADER_DATA_TYPE_INT64_X16,
+    VSC_SHADER_DATA_TYPE_INT64_X32,
+
+    /* packed data type */
+
+    /* packed float16 (2 bytes per element) */
+    VSC_SHADER_DATA_TYPE_FLOAT16_P2,
+    VSC_SHADER_DATA_TYPE_FLOAT16_P3,
+    VSC_SHADER_DATA_TYPE_FLOAT16_P4,
+    VSC_SHADER_DATA_TYPE_FLOAT16_P8,
+    VSC_SHADER_DATA_TYPE_FLOAT16_P16,
+    VSC_SHADER_DATA_TYPE_FLOAT16_P32,
+
+    /* packed boolean (1 byte per element) */
+    VSC_SHADER_DATA_TYPE_BOOLEAN_P2,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_P3,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_P4,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_P8,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_P16,
+    VSC_SHADER_DATA_TYPE_BOOLEAN_P32,
+
+    /* uchar vectors (1 byte per element) */
+    VSC_SHADER_DATA_TYPE_UINT8_P2,
+    VSC_SHADER_DATA_TYPE_UINT8_P3,
+    VSC_SHADER_DATA_TYPE_UINT8_P4,
+    VSC_SHADER_DATA_TYPE_UINT8_P8,
+    VSC_SHADER_DATA_TYPE_UINT8_P16,
+    VSC_SHADER_DATA_TYPE_UINT8_P32,
+
+    /* char vectors (1 byte per element) */
+    VSC_SHADER_DATA_TYPE_INT8_P2,
+    VSC_SHADER_DATA_TYPE_INT8_P3,
+    VSC_SHADER_DATA_TYPE_INT8_P4,
+    VSC_SHADER_DATA_TYPE_INT8_P8,
+    VSC_SHADER_DATA_TYPE_INT8_P16,
+    VSC_SHADER_DATA_TYPE_INT8_P32,
+
+    /* ushort vectors (2 bytes per element) */
+    VSC_SHADER_DATA_TYPE_UINT16_P2,
+    VSC_SHADER_DATA_TYPE_UINT16_P3,
+    VSC_SHADER_DATA_TYPE_UINT16_P4,
+    VSC_SHADER_DATA_TYPE_UINT16_P8,
+    VSC_SHADER_DATA_TYPE_UINT16_P16,
+    VSC_SHADER_DATA_TYPE_UINT16_P32,
+
+    /* short vectors (2 bytes per element) */
+    VSC_SHADER_DATA_TYPE_INT16_P2,
+    VSC_SHADER_DATA_TYPE_INT16_P3,
+    VSC_SHADER_DATA_TYPE_INT16_P4,
+    VSC_SHADER_DATA_TYPE_INT16_P8,
+    VSC_SHADER_DATA_TYPE_INT16_P16,
+    VSC_SHADER_DATA_TYPE_INT16_P32,
+
+    /* matrix type: only support float type */
+    VSC_SHADER_DATA_TYPE_FLOAT_2X2,
+    VSC_SHADER_DATA_TYPE_FLOAT_3X3,
+    VSC_SHADER_DATA_TYPE_FLOAT_4X4,
+    VSC_SHADER_DATA_TYPE_FLOAT_2X3,
+    VSC_SHADER_DATA_TYPE_FLOAT_2X4,
+    VSC_SHADER_DATA_TYPE_FLOAT_3X2,
+    VSC_SHADER_DATA_TYPE_FLOAT_3X4,
+    VSC_SHADER_DATA_TYPE_FLOAT_4X2,
+    VSC_SHADER_DATA_TYPE_FLOAT_4X3,
+
+    VSC_SHADER_DATA_TYPE_FLOAT16_2X2,
+    VSC_SHADER_DATA_TYPE_FLOAT16_3X3,
+    VSC_SHADER_DATA_TYPE_FLOAT16_4X4,
+    VSC_SHADER_DATA_TYPE_FLOAT16_2X3,
+    VSC_SHADER_DATA_TYPE_FLOAT16_2X4,
+    VSC_SHADER_DATA_TYPE_FLOAT16_3X2,
+    VSC_SHADER_DATA_TYPE_FLOAT16_3X4,
+    VSC_SHADER_DATA_TYPE_FLOAT16_4X2,
+    VSC_SHADER_DATA_TYPE_FLOAT16_4X3,
+
+    VSC_SHADER_DATA_TYPE_FLOAT64_2X2,
+    VSC_SHADER_DATA_TYPE_FLOAT64_3X3,
+    VSC_SHADER_DATA_TYPE_FLOAT64_4X4,
+    VSC_SHADER_DATA_TYPE_FLOAT64_2X3,
+    VSC_SHADER_DATA_TYPE_FLOAT64_2X4,
+    VSC_SHADER_DATA_TYPE_FLOAT64_3X2,
+    VSC_SHADER_DATA_TYPE_FLOAT64_3X4,
+    VSC_SHADER_DATA_TYPE_FLOAT64_4X2,
+    VSC_SHADER_DATA_TYPE_FLOAT64_4X3,
+
+    /* sampler type */
+    VSC_SHADER_DATA_TYPE_MIN_SAMPLER_TYID,
+    VSC_SHADER_DATA_TYPE_SAMPLER_1D = VSC_SHADER_DATA_TYPE_MIN_SAMPLER_TYID,
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D,
+    VSC_SHADER_DATA_TYPE_SAMPLER_3D,
+    VSC_SHADER_DATA_TYPE_SAMPLER_CUBIC,
+    VSC_SHADER_DATA_TYPE_SAMPLER_CUBE_ARRAY,
+    VSC_SHADER_DATA_TYPE_SAMPLER,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_1D,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_2D,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_3D,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_CUBIC,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_CUBE_ARRAY,
+    VSC_SHADER_DATA_TYPE_USAMPLER_1D,
+    VSC_SHADER_DATA_TYPE_USAMPLER_2D,
+    VSC_SHADER_DATA_TYPE_USAMPLER_3D,
+    VSC_SHADER_DATA_TYPE_USAMPLER_CUBIC,
+    VSC_SHADER_DATA_TYPE_USAMPLER_CUBE_ARRAY,
+    VSC_SHADER_DATA_TYPE_SAMPLER_EXTERNAL_OES,
+
+    VSC_SHADER_DATA_TYPE_SAMPLER_1D_SHADOW,
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D_SHADOW,
+    VSC_SHADER_DATA_TYPE_SAMPLER_CUBE_SHADOW,
+    VSC_SHADER_DATA_TYPE_SAMPLER_CUBE_ARRAY_SHADOW,
+
+    VSC_SHADER_DATA_TYPE_SAMPLER_1D_ARRAY,
+    VSC_SHADER_DATA_TYPE_SAMPLER_1D_ARRAY_SHADOW,
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D_ARRAY,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_2D_ARRAY,
+    VSC_SHADER_DATA_TYPE_USAMPLER_2D_ARRAY,
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D_ARRAY_SHADOW,
+
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D_MS,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_2D_MS,
+    VSC_SHADER_DATA_TYPE_USAMPLER_2D_MS,
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D_MS_ARRAY,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_2D_MS_ARRAY,
+    VSC_SHADER_DATA_TYPE_USAMPLER_2D_MS_ARRAY,
+    VSC_SHADER_DATA_TYPE_SAMPLER_BUFFER,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_BUFFER,
+    VSC_SHADER_DATA_TYPE_USAMPLER_BUFFER,
+    VSC_SHADER_DATA_TYPE_VIV_GENERIC_GL_SAMPLER,
+    VSC_SHADER_DATA_TYPE_MAX_SAMPLER_TYID = VSC_SHADER_DATA_TYPE_VIV_GENERIC_GL_SAMPLER,
+
+    /* image type */
+    VSC_SHADER_DATA_TYPE_MIN_IMAGE_TYID,
+    /* subPass input */
+    VSC_SHADER_DATA_TYPE_SUBPASSINPUT = VSC_SHADER_DATA_TYPE_MIN_IMAGE_TYID,
+    VSC_SHADER_DATA_TYPE_SUBPASSINPUTMS,
+    VSC_SHADER_DATA_TYPE_ISUBPASSINPUT,
+    VSC_SHADER_DATA_TYPE_ISUBPASSINPUTMS,
+    VSC_SHADER_DATA_TYPE_USUBPASSINPUT,
+    VSC_SHADER_DATA_TYPE_USUBPASSINPUTMS,
+
+    VSC_SHADER_DATA_TYPE_IMAGE_1D,
+    VSC_SHADER_DATA_TYPE_IMAGE_1D_DEPTH,
+    VSC_SHADER_DATA_TYPE_IMAGE_1D_ARRAY,
+    VSC_SHADER_DATA_TYPE_IMAGE_1D_ARRAY_DEPTH,
+    VSC_SHADER_DATA_TYPE_IMAGE_1D_BUFFER,
+    VSC_SHADER_DATA_TYPE_IIMAGE_1D,
+    VSC_SHADER_DATA_TYPE_IIMAGE_1D_ARRAY,
+    VSC_SHADER_DATA_TYPE_UIMAGE_1D,
+    VSC_SHADER_DATA_TYPE_UIMAGE_1D_ARRAY,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_ARRAY,
+    VSC_SHADER_DATA_TYPE_IMAGE_3D,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_MSSA,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_ARRAY_MSSA,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_MSSA_DEPTH,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_ARRAY_MSSA_DEPTH,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_DEPTH,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_ARRAY_DEPTH,
+    VSC_SHADER_DATA_TYPE_IIMAGE_2D,
+    VSC_SHADER_DATA_TYPE_IIMAGE_2D_MSSA,
+    VSC_SHADER_DATA_TYPE_IIMAGE_2D_ARRAY_MSSA,
+    VSC_SHADER_DATA_TYPE_UIMAGE_2D,
+    VSC_SHADER_DATA_TYPE_UIMAGE_2D_MSSA,
+    VSC_SHADER_DATA_TYPE_UIMAGE_2D_ARRAY_MSSA,
+    VSC_SHADER_DATA_TYPE_IIMAGE_3D,
+    VSC_SHADER_DATA_TYPE_UIMAGE_3D,
+    VSC_SHADER_DATA_TYPE_IIMAGE_2D_ARRAY,
+    VSC_SHADER_DATA_TYPE_UIMAGE_2D_ARRAY,
+    VSC_SHADER_DATA_TYPE_IMAGE_CUBE,
+    VSC_SHADER_DATA_TYPE_IMAGE_CUBE_DEPTH,
+    VSC_SHADER_DATA_TYPE_IMAGE_CUBE_ARRAY,
+    VSC_SHADER_DATA_TYPE_IMAGE_CUBE_DEPTH_ARRAY,
+    VSC_SHADER_DATA_TYPE_IIMAGE_CUBE,
+    VSC_SHADER_DATA_TYPE_IIMAGE_CUBE_DEPTH,
+    VSC_SHADER_DATA_TYPE_IIMAGE_CUBE_ARRAY,
+    VSC_SHADER_DATA_TYPE_UIMAGE_CUBE,
+    VSC_SHADER_DATA_TYPE_UIMAGE_CUBE_DEPTH,
+    VSC_SHADER_DATA_TYPE_UIMAGE_CUBE_ARRAY,
+    VSC_SHADER_DATA_TYPE_IMAGE_BUFFER,
+    VSC_SHADER_DATA_TYPE_IIMAGE_BUFFER,
+    VSC_SHADER_DATA_TYPE_UIMAGE_BUFFER,
+    VSC_SHADER_DATA_TYPE_VIV_GENERIC_GL_IMAGE,
+    VSC_SHADER_DATA_TYPE_MAX_IMAGE_TYID = VSC_SHADER_DATA_TYPE_VIV_GENERIC_GL_IMAGE,
+
+    /* For OCL */
+    VSC_SHADER_DATA_TYPE_MIN_IMAGE_T_TYID,
+    VSC_SHADER_DATA_TYPE_IMAGE_1D_T = VSC_SHADER_DATA_TYPE_MIN_IMAGE_T_TYID,
+    VSC_SHADER_DATA_TYPE_IMAGE_1D_BUFFER_T,
+    VSC_SHADER_DATA_TYPE_IMAGE_1D_ARRAY_T,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_T,
+    VSC_SHADER_DATA_TYPE_IMAGE_2D_ARRAY_T,
+    VSC_SHADER_DATA_TYPE_IMAGE_3D_T,
+    VSC_SHADER_DATA_TYPE_VIV_GENERIC_IMAGE_T,
+    VSC_SHADER_DATA_TYPE_MAX_IMAGE_T_TYID = VSC_SHADER_DATA_TYPE_VIV_GENERIC_IMAGE_T,
+    VSC_SHADER_DATA_TYPE_SAMPLER_T,
+    VSC_SHADER_DATA_TYPE_EVENT_T,
+
+    /* atomic counter type */
+    VSC_SHADER_DATA_TYPE_MIN_ATOMIC_COUNTER_TYPID,
+    VSC_SHADER_DATA_TYPE_ATOMIC_UINT = VSC_SHADER_DATA_TYPE_MIN_ATOMIC_COUNTER_TYPID,
+    VSC_SHADER_DATA_TYPE_ATOMIC_UINT4,
+    VSC_SHADER_DATA_TYPE_MAX_ATOMIC_COUNTER_TYPID = VSC_SHADER_DATA_TYPE_ATOMIC_UINT4,
+
+    /* OpenGL 4.0 types */
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D_RECT,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_2D_RECT,
+    VSC_SHADER_DATA_TYPE_USAMPLER_2D_RECT,
+    VSC_SHADER_DATA_TYPE_SAMPLER_2D_RECT_SHADOW,
+    VSC_SHADER_DATA_TYPE_ISAMPLER_1D_ARRAY,
+    VSC_SHADER_DATA_TYPE_USAMPLER_1D_ARRAY,
+
+    VSC_SHADER_DATA_TYPE_PRIMITIVETYPE_COUNT,
+    VSC_SHADER_DATA_TYPE_LAST_PRIMITIVETYPE = VSC_SHADER_DATA_TYPE_PRIMITIVETYPE_COUNT-1,
+}
+VSC_SHADER_DATA_TYPE;
+
+/* Copy from VIR_ImageFormat. */
+/* Any modification here, please do the corresponding change for VIR_ImageFormat. */
+typedef enum _VSC_IMAGE_FORMAT
+{
+    VSC_IMAGE_FORMAT_NONE = 0x00000000,
+    /*F32.*/
+    VSC_IMAGE_FORMAT_RGBA32F,
+    VSC_IMAGE_FORMAT_RG32F,
+    VSC_IMAGE_FORMAT_R32F,
+    /*I32.*/
+    VSC_IMAGE_FORMAT_RGBA32I,
+    VSC_IMAGE_FORMAT_RG32I,
+    VSC_IMAGE_FORMAT_R32I,
+    /*UI32.*/
+    VSC_IMAGE_FORMAT_RGBA32UI,
+    VSC_IMAGE_FORMAT_RG32UI,
+    VSC_IMAGE_FORMAT_R32UI,
+    /*F16.*/
+    VSC_IMAGE_FORMAT_RGBA16F,
+    VSC_IMAGE_FORMAT_RG16F,
+    VSC_IMAGE_FORMAT_R16F,
+    /*I16.*/
+    VSC_IMAGE_FORMAT_RGBA16I,
+    VSC_IMAGE_FORMAT_RG16I,
+    VSC_IMAGE_FORMAT_R16I,
+    /*UI16.*/
+    VSC_IMAGE_FORMAT_RGBA16UI,
+    VSC_IMAGE_FORMAT_RG16UI,
+    VSC_IMAGE_FORMAT_R16UI,
+    /*F16 SNORM/UNORM.*/
+    VSC_IMAGE_FORMAT_RGBA16,
+    VSC_IMAGE_FORMAT_RGBA16_SNORM,
+    VSC_IMAGE_FORMAT_RG16,
+    VSC_IMAGE_FORMAT_RG16_SNORM,
+    VSC_IMAGE_FORMAT_R16,
+    VSC_IMAGE_FORMAT_R16_SNORM,
+    /*F8 SNORM/UNORM.*/
+    VSC_IMAGE_FORMAT_BGRA8_UNORM,
+    VSC_IMAGE_FORMAT_RGBA8,
+    VSC_IMAGE_FORMAT_RGBA8_SNORM,
+    VSC_IMAGE_FORMAT_RG8,
+    VSC_IMAGE_FORMAT_RG8_SNORM,
+    VSC_IMAGE_FORMAT_R8,
+    VSC_IMAGE_FORMAT_R8_SNORM,
+    /*I8.*/
+    VSC_IMAGE_FORMAT_RGBA8I,
+    VSC_IMAGE_FORMAT_RG8I,
+    VSC_IMAGE_FORMAT_R8I,
+    /*UI8.*/
+    VSC_IMAGE_FORMAT_RGBA8UI,
+    VSC_IMAGE_FORMAT_RG8UI,
+    VSC_IMAGE_FORMAT_R8UI,
+    /*F-PACK.*/
+    VSC_IMAGE_FORMAT_R5G6B5_UNORM_PACK16,
+    VSC_IMAGE_FORMAT_ABGR8_UNORM_PACK32,
+    VSC_IMAGE_FORMAT_ABGR8I_PACK32,
+    VSC_IMAGE_FORMAT_ABGR8UI_PACK32,
+    VSC_IMAGE_FORMAT_A2R10G10B10_UNORM_PACK32,
+    VSC_IMAGE_FORMAT_A2B10G10R10_UNORM_PACK32,
+    VSC_IMAGE_FORMAT_A2B10G10R10UI_PACK32,
+} VSC_IMAGE_FORMAT;
+
+typedef enum _VSC_ADDRSPACE
+{
+    VIR_AS_PRIVATE, /* private address space */
+    VIR_AS_GLOBAL, /* global address space */
+    VIR_AS_CONSTANT, /* constant address space, uniform mapped to this space */
+    VIR_AS_LOCAL            /* local address space, function scope locals mappped
+                               into this space */
+} VSC_AddrSpace;
+
+typedef enum _VSC_TYQUALIFIER
+{
+    VIR_TYQUAL_NONE         = 0x00, /* unqualified */
+    VIR_TYQUAL_CONST        = 0x01, /* const */
+    VIR_TYQUAL_VOLATILE     = 0x02, /* volatile */
+    VIR_TYQUAL_RESTRICT     = 0x04, /* restrict */
+    VIR_TYQUAL_READ_ONLY    = 0x08, /* readonly */
+    VIR_TYQUAL_WRITE_ONLY   = 0x10, /* writeonly */
+    VIR_TYQUAL_CONSTANT     = 0x20, /* constant address space */
+    VIR_TYQUAL_GLOBAL       = 0x40, /* global address space */
+    VIR_TYQUAL_LOCAL        = 0x80, /* local address space */
+    VIR_TYQUAL_PRIVATE      = 0x100, /* private address space */
+} VSC_TyQualifier;
+
+typedef VSC_AddrSpace        VIR_AddrSpace;
+typedef VSC_TyQualifier      VIR_TyQualifier;
+
+/* for different HW, we use different instruction to implement OCL image read/write
+ * to achieve best performance */
+typedef enum {
+    VSC_OCLImgLibKind_UseLoadStore       = 0, /* for v54x GC chips, use LOAD/STORE/TEXLD */
+    VSC_OCLImgLibKind_UseImgLoadTexldU   = 1, /* for v55 GC chips, use IMG_LOAD/IMG_STORE/TEXLD_U */
+    VSC_OCLImgLibKind_UseImgLoadTexldUXY = 2, /* for v60 GC and v620 GC chips */
+    VSC_OCLImgLibKind_UseImgLoadVIP      = 3, /* v60 VIP chip, use IMG_LOAD/IMG_STORE */
+    VSC_OCLImgLibKind_Counts, /* count of img libs */
+    VSC_OCLImgLibKind_BasedOnHWFeature         /* select library based on HW feature */
+} VSC_OCLImgLibKind;
+
+typedef enum
+{
+    VSC_ImageValueFloat      = 0, /* float type: read_imagef */
+    VSC_ImageValueInt        = 1, /* int type: read_imagei */
+    VSC_ImageValueUint       = 2        /* unsigned int type: read_imageui */
+} vscImageValueType;
+
+typedef union _VSC_Image_desc {
+    struct {
+        /* the first 4 32-bits are the same as HW imge_desc as of V630 */
+        gctUINT   baseAddress;          /* base address of image data */
+        gctUINT   row_stride;           /* the row stride (byte) of the image */
+        gctUINT   width          : 16;  /* the width of image (pixels) */
+        gctUINT   height         : 16;  /* the height of image (rows) */
+
+        gctUINT   shift          : 3;   /* Shift value for index. */
+        gctUINT   multiply       : 1;   /* Value to multiply index with. */
+        gctUINT   addressing     : 2;   /* Addressing mode for LOAD_IMG and STORE_IMG. */
+        gctUINT   conversion     : 4;   /* Conversion format. */
+        gctUINT   titling        : 2;   /* titling */
+        gctUINT   image1Dor2D    : 1;   /* 1D or 2D image */
+        gctUINT   imageId0       : 1;   /* ImageID bit0. */
+        gctUINT   componentCount : 2;   /* Component count. */
+        gctUINT   swizzleR       : 3;   /* swizzle for red */
+        gctUINT   imageId1       : 1;   /* ImageID bit1. */
+        gctUINT   swizzleG       : 3;   /* swizzle for green */
+        gctUINT   imageId2       : 1;   /* ImageID bit2. */
+        gctUINT   swizzleB       : 3;   /* swizzle for blue */
+        gctUINT   reserved0      : 1;
+        gctUINT   swizzleA       : 3;   /* swizzle for alpha */
+        gctUINT   reserved1      : 1;
+
+        /* following data are used by SW to calculate 3D image slice image address
+         * and image query data */
+        gctUINT   sliceSize;            /* slice size for image 3D */
+        gctUINT   depth_arraySize : 16; /* depth for image 3D, or array_size for image1D/2D array */
+        gctUINT   imageType       : 16; /* vscImageValueType: 1D: 0, 1D_buffer: 1, 1D_array: 2, 2D: 3, 2D_array: 4, 3D: 5 */
+        gctUINT   channelOrder    : 16; /* image channel order */
+        gctUINT   channelDataType : 16; /* image channel data type */
+        gctUINT   imageValueType  : 2;  /* vscImageValueType (float/int/uint), filled by compiler */
+        gctUINT   reserved2       : 30;
+    } sd;  /* structured data */
+    gctUINT rawbits[8];
+} VSC_ImageDesc;
+
+typedef enum _VSC_SAMPLER_VALUE
+{
+
+    /* First byte: addressing mode. */
+    VSC_IMG_SAMPLER_ADDRESS_NONE                = 0x00, /* (CL_ADDRESS_NONE            & 0xFF) */
+    VSC_IMG_SAMPLER_ADDRESS_CLAMP_TO_EDGE       = 0x01, /* (CL_ADDRESS_CLAMP_TO_EDGE   & 0xFF),*/
+    VSC_IMG_SAMPLER_ADDRESS_CLAMP               = 0x02, /* CL_ADDRESS_CLAMP            & 0xFF), */
+    VSC_IMG_SAMPLER_ADDRESS_REPEAT              = 0x03, /* CL_ADDRESS_REPEAT           & 0xFF), */
+    VSC_IMG_SAMPLER_ADDRESS_MIRRORED_REPEAT     = 0x04, /* CL_ADDRESS_MIRRORED_REPEAT  & 0xFF), */
+    VSC_IMG_SAMPLER_ADDRESS_COUNT               = 0x05, /* the count of address mode */
+    /* Second byte: filter mode. */
+    VSC_IMG_SAMPLER_FILTER_NEAREST              = 0x0000, /* (CL_FILTER_NEAREST  & 0xFF00) << 8), */
+    VSC_IMG_SAMPLER_FILTER_LINEAR               = 0x0100, /* (CL_FILTER_LINEAR   & 0xFF00) << 8), */
+
+    /* Third byte: normalized coords. */
+    VSC_IMG_SAMPLER_NORMALIZED_COORDS_FALSE     = 0x000000, /*0x0 << 16), */
+    VSC_IMG_SAMPLER_NORMALIZED_COORDS_TRUE      = 0x010000, /*0x1 << 16)    */
+
+    /* we treat int or float coordinate type as sampler value,
+     * so the <image, sampler> pair will carry the int coordinate info
+     * which is useful when construct image read lib function name
+     */
+    VSC_IMG_SAMPLER_INT_COORDS_FALSE            = 0x0000000, /*0x0 << 24), */
+    VSC_IMG_SAMPLER_INT_COORDS_TRUE             = 0x1000000, /*0x1 << 24)    */
+
+    VSC_IMG_SAMPLER_DEFAULT_VALUE               = VSC_IMG_SAMPLER_ADDRESS_NONE |
+                                                  VSC_IMG_SAMPLER_FILTER_NEAREST |
+                                                  VSC_IMG_SAMPLER_NORMALIZED_COORDS_FALSE |
+                                                  VSC_IMG_SAMPLER_INT_COORDS_FALSE,
+    VSC_IMG_SAMPLER_UNKNOWN_VALUE               = 0x7FFFFFFF, /* unkown sampler value marker */
+    VSC_IMG_SAMPLER_INVALID_VALUE               = 0x7FFFFFFF, /* invalid value marker */
+} VSC_SamplerValue;
+
+#define VIR_IMG_isSamplerLinearFilter(sampler)      (((sampler)&((gctUINT)VSC_IMG_SAMPLER_FILTER_LINEAR)) != 0)
+#define VIR_IMG_isSamplerNearestFilter(sampler)     (((sampler)&((gctUINT)VSC_IMG_SAMPLER_FILTER_LINEAR)) == 0)
+#define VIR_IMG_isSamplerNormalizedCoords(sampler)  (((sampler)&((gctUINT)VSC_IMG_SAMPLER_NORMALIZED_COORDS_TRUE)) != 0)
+#define VIR_IMG_isSamplerIntCoords(sampler)         (((sampler)&((gctUINT)VSC_IMG_SAMPLER_INT_COORDS_TRUE)) != 0)
+#define VIR_IMG_GetSamplerAddressMode(sampler)      ((VSC_SamplerValue)((sampler)&0xFF))
+
+typedef void* DRIVER_HANDLE;
+
+/* Callback defintions. Note that first param of all drv-callbacks must be hDrv which
+   designates the specific client driver who needs insure param hDrv of callbacks and
+   VSC_SYS_CONTEXT::hDrv point to the same underlying true driver object (driver-contex/
+   driver device/...) */
+typedef void* (*PFN_ALLOC_VIDMEM_CB)(DRIVER_HANDLE hDrv,
+                                     gceSURF_TYPE type,
+                                     gctSTRING tag,
+                                     gctSIZE_T size,
+                                     gctUINT32 align,
+                                     gctPOINTER* ppOpaqueNode,
+                                     gctPOINTER* ppVirtualAddr,
+                                     gctUINT32* pPhysicalAddr,
+                                     gctPOINTER pInitialData,
+                                     gctBOOL bZeroMemory);
+typedef void* (*PFN_FREE_VIDMEM_CB)(DRIVER_HANDLE hDrv,
+                                    gceSURF_TYPE type,
+                                    gctSTRING tag,
+                                    gctPOINTER pOpaqueNode);
+
+typedef struct _VSC_DRV_CALLBACKS
+{
+    PFN_ALLOC_VIDMEM_CB pfnAllocVidMemCb;
+    PFN_FREE_VIDMEM_CB  pfnFreeVidMemCb;
+}VSC_DRV_CALLBACKS, *PVSC_DRV_CALLBACKS;
+
+/* VSC hardware (chip) configuration that poses on (re)-compiling */
+typedef struct _VSC_HW_CONFIG
+{
+    struct
+    {
+        /* word 0 */
+        gctUINT          hasHalti0              : 1;
+        gctUINT          hasHalti1              : 1;
+        gctUINT          hasHalti2              : 1;
+        gctUINT          hasHalti3              : 1;
+        gctUINT          hasHalti4              : 1;
+        gctUINT          hasHalti5              : 1;
+        gctUINT          supportGS              : 1;
+        gctUINT          supportTS              : 1;
+
+        gctUINT          supportInteger         : 1;
+        gctUINT          hasSignFloorCeil       : 1;
+        gctUINT          hasSqrtTrig            : 1;
+        gctUINT          hasNewSinCosLogDiv     : 1;
+        gctUINT          canBranchOnImm         : 1;
+        gctUINT          supportDual16          : 1;
+        gctUINT          hasBugFix8             : 1;
+        gctUINT          hasBugFix10            : 1;
+
+        gctUINT          hasBugFix11            : 1;
+        gctUINT          hasSelectMapSwizzleFix : 1;
+        gctUINT          hasSamplePosSwizzleFix : 1;
+        gctUINT          hasLoadAttrOOBFix      : 1;
+        gctUINT          hasSampleMaskInR0ZWFix : 1;
+        gctUINT          hasICacheAllocCountFix : 1;
+        gctUINT          hasSHEnhance2          : 1;
+        gctUINT          hasMediumPrecision     : 1;
+
+        gctUINT          hasInstCache           : 1;
+        gctUINT          hasInstCachePrefetch   : 1;
+        gctUINT          instBufferUnified      : 1;
+        /* Every single shader stage can use all constant registers. */
+        gctUINT          constRegFileUnified    : 1;
+        /* Every single shader stage can use all sampler registers. */
+        gctUINT          samplerRegFileUnified  : 1;
+        gctUINT          bigEndianMI            : 1;
+        gctUINT          raPushPosW             : 1;
+        gctUINT          vtxInstanceIdAsAttr    : 1;
+
+        /* word 1 */
+        gctUINT          vtxInstanceIdAsInteger : 1;
+        gctUINT          gsSupportEmit          : 1;
+        gctUINT          highpVaryingShift      : 1;
+        gctUINT          needCLXFixes           : 1;
+        gctUINT          needCLXEFixes          : 1;
+        gctUINT          flatDual16Fix          : 1;
+        gctUINT          supportEVIS            : 1;
+        gctUINT          supportImgAtomic       : 1;
+
+        gctUINT          supportAdvancedInsts   : 1;
+        gctUINT          noOneConstLimit        : 1;
+        gctUINT          hasUniformB0           : 1;
+        gctUINT          supportOOBCheck        : 1;
+        gctUINT          hasUniversalTexld      : 1;
+        gctUINT          hasUniversalTexldV2    : 1;
+        gctUINT          hasTexldUFix           : 1;
+        gctUINT          canSrc0OfImgLdStBeTemp : 1;
+
+        gctUINT          hasPSIOInterlock       : 1;
+        gctUINT          support128BppImage     : 1;
+        gctUINT          supportMSAATexture     : 1;
+        gctUINT          supportPerCompDepForLS : 1;
+        gctUINT          supportImgAddr         : 1;
+        gctUINT          hasUscGosAddrFix       : 1;
+        gctUINT          multiCluster           : 1;
+        gctUINT          smallBatch             : 1;
+
+        gctUINT          hasImageOutBoundaryFix : 1;
+        gctUINT          supportTexldCoordOffset: 1;
+        gctUINT          supportLSAtom          : 1;
+        gctUINT          supportUnOrdBranch     : 1;
+        gctUINT          supportPatchVerticesIn : 1;
+        gctUINT          hasHalfDepFix          : 1;
+        gctUINT          supportUSC             : 1;
+        gctUINT          supportPartIntBranch   : 1;
+
+        /* word 2 */
+        gctUINT          supportIntAttrib       : 1;
+        gctUINT          hasTxBiasLodFix        : 1;
+        gctUINT          supportmovai           : 1;
+        gctUINT          useGLZ                 : 1;
+        gctUINT          supportHelperInv       : 1;
+        gctUINT          supportAdvBlendPart0   : 1;
+        gctUINT          supportStartVertexFE   : 1;
+        gctUINT          supportTxGather        : 1;
+
+        gctUINT          singlePipeHalti1       : 1;
+        gctUINT          supportEVISVX2         : 1;
+        gctUINT          computeOnly            : 1;
+        gctUINT          hasBugFix7             : 1;
+        gctUINT          hasExtraInst2          : 1;
+        gctUINT          hasAtomic              : 1;
+        gctUINT          supportFullIntBranch   : 1;
+        /* All shader stages can use the same constant register at the same time. */
+        gctUINT          supportUnifiedConstant : 1;
+
+        /* All shader stages can use the same sampler register at the same time. */
+        gctUINT          supportUnifiedSampler  : 1;
+        gctUINT          support32BitIntDiv     : 1;
+        gctUINT          supportFullCompIntDiv  : 1;
+        gctUINT          supportComplex         : 1;
+        gctUINT          supportBigEndianLdSt   : 1;
+        gctUINT          supportUSCUnalloc      : 1;
+        gctUINT          supportEndOfBBReissue  : 1;
+        gctUINT          hasDynamicIdxDepFix    : 1;
+
+        gctUINT          supportPSCSThrottle    : 1;
+        gctUINT          hasLODQFix             : 1;
+        gctUINT          supportHWManagedLS     : 1;
+        gctUINT          hasScatteredMemAccess  : 1;
+        gctUINT          supportImgLDSTClamp    : 1;
+        gctUINT          useSrc0SwizzleAsSrcBin : 1;
+        gctUINT          supportSeparatedTex    : 1;
+        gctUINT          supportMultiGPU        : 1;
+
+        /* word 3 */
+        gctUINT          hasPointSizeFix        : 1;
+        gctUINT          supportVectorB0        : 1;
+        gctUINT          reserved1              : 30;
+
+        /* Last word */
+        /* Followings will be removed after shader programming is removed out of VSC */
+        gctUINT          hasSHEnhance3          : 1;
+        gctUINT          rtneRoundingEnabled    : 1;
+        gctUINT          hasThreadWalkerInPS    : 1;
+        gctUINT          newSteeringICacheFlush : 1;
+        gctUINT          has32Attributes        : 1;
+        gctUINT          hasSamplerBaseOffset   : 1;
+        gctUINT          supportStreamOut       : 1;
+        gctUINT          supportZeroAttrsInFE   : 1;
+
+        gctUINT          outputCountFix         : 1;
+        gctUINT          varyingPackingLimited  : 1;
+        gctUINT          robustAtomic           : 1;
+        gctUINT          newGPIPE               : 1;
+        gctUINT          FEDrawDirect           : 1;
+
+        gctUINT          hasUSCAtomicFix2       : 1;
+        gctUINT          reserved2              : 18;
+    } hwFeatureFlags;
+
+    gctUINT              chipModel;
+    gctUINT              chipRevision;
+    gctUINT              productID;
+    gctUINT              customerID;
+    gctUINT              maxCoreCount;
+    gctUINT              maxThreadCountPerCore;
+    gctUINT              maxVaryingCount;
+    gctUINT              maxAttributeCount;
+    gctUINT              maxRenderTargetCount;
+    gctUINT              maxGPRCountPerCore;
+    gctUINT              maxGPRCountPerThread;
+    gctUINT              maxHwNativeTotalInstCount;
+    gctUINT              maxTotalInstCount;
+    gctUINT              maxVSInstCount;
+    gctUINT              maxPSInstCount;
+    gctUINT              maxHwNativeTotalConstRegCount;
+    gctUINT              maxTotalConstRegCount;
+    gctUINT              unifiedConst;
+    gctUINT              maxVSConstRegCount;
+    gctUINT              maxTCSConstRegCount;  /* HS */
+    gctUINT              maxTESConstRegCount;  /* DS */
+    gctUINT              maxGSConstRegCount;
+    gctUINT              maxPSConstRegCount;
+    gctUINT              vsSamplerRegNoBase;
+    gctUINT              tcsSamplerRegNoBase;  /* HS */
+    gctUINT              tesSamplerRegNoBase;  /* DS */
+    gctUINT              gsSamplerRegNoBase;
+    gctUINT              psSamplerRegNoBase;
+    gctUINT              csSamplerRegNoBase;
+    gctUINT              maxVSSamplerCount;
+    gctUINT              maxTCSSamplerCount;   /* HS */
+    gctUINT              maxTESSamplerCount;   /* DS */
+    gctUINT              maxGSSamplerCount;
+    gctUINT              maxPSSamplerCount;
+    gctUINT              maxCSSamplerCount;
+    gctUINT              maxHwNativeTotalSamplerCount;
+    gctUINT              maxSamplerCountPerShader;
+    gctUINT              maxUSCAttribBufInKbyte;     /* usc size for non-cache part */
+    gctUINT              maxLocalMemSizeInByte; /* local memory size */
+    gctUINT              maxResultCacheWinSize;
+    gctUINT              vsSamplerNoBaseInInstruction;
+    gctUINT              psSamplerNoBaseInInstruction;
+    gctFLOAT             minPointSize;
+    gctFLOAT             maxPointSize;
+
+    /* Caps for workGroupSize. */
+    gctUINT              initWorkGroupSizeToCalcRegCount;
+    gctUINT              maxWorkGroupSize;
+    gctUINT              minWorkGroupSize;
+
+    /* Followings will be removed after shader programming is removed out of VSC */
+    gctUINT              vsInstBufferAddrBase;
+    gctUINT              psInstBufferAddrBase;
+    gctUINT              vsConstRegAddrBase;
+    gctUINT              tcsConstRegAddrBase;
+    gctUINT              tesConstRegAddrBase;
+    gctUINT              gsConstRegAddrBase;
+    gctUINT              psConstRegAddrBase;
+    gctUINT              vertexOutputBufferSize;
+    gctUINT              vertexCacheSize;
+    gctUINT              ctxStateCount;
+}VSC_HW_CONFIG, *PVSC_HW_CONFIG;
+
+typedef gcsGLSLCaps VSC_GL_API_CONFIG, *PVSC_GL_API_CONFIG;
+
+/* VSC supported optional opts */
+#define VSC_COMPILER_OPT_NONE                           0x0000000000000000ULL
+
+#define VSC_COMPILER_OPT_ALGE_SIMP                      0x0000000000000001ULL
+#define VSC_COMPILER_OPT_GCP                            0x0000000000000002ULL
+#define VSC_COMPILER_OPT_LCP                            0x0000000000000004ULL
+#define VSC_COMPILER_OPT_LCSE                           0x0000000000000008ULL
+#define VSC_COMPILER_OPT_DCE                            0x0000000000000010ULL
+#define VSC_COMPILER_OPT_PRE                            0x0000000000000020ULL
+#define VSC_COMPILER_OPT_PEEPHOLE                       0x0000000000000040ULL
+#define VSC_COMPILER_OPT_CONSTANT_PROPOGATION           0x0000000000000080ULL
+#define VSC_COMPILER_OPT_CONSTANT_FOLDING               0x0000000000000100ULL
+#define VSC_COMPILER_OPT_FUNC_INLINE                    0x0000000000000200ULL
+#define VSC_COMPILER_OPT_INST_SKED                      0x0000000000000400ULL
+#define VSC_COMPILER_OPT_GPR_SPILLABLE                  0x0000000000000800ULL
+#define VSC_COMPILER_OPT_CONSTANT_REG_SPILLABLE         0x0000000000001000ULL
+#define VSC_COMPILER_OPT_VEC                            0x0000000000002000ULL /* Including logic io packing */
+#define VSC_COMPILER_OPT_IO_PACKING                     0x0000000000004000ULL /* Physical io packing */
+#define VSC_COMPILER_OPT_FULL_ACTIVE_IO                 0x0000000000008000ULL
+#define VSC_COMPILER_OPT_DUAL16                         0x0000000000010000ULL
+#define VSC_COMPILER_OPT_ILF_LINK                       0x0000000000020000ULL
+
+#define VSC_COMPILER_OPT_FULL                           0x000000000003FFFFULL
+
+#define VSC_COMPILER_OPT_NO_ALGE_SIMP                   0x0000000100000000ULL
+#define VSC_COMPILER_OPT_NO_GCP                         0x0000000200000000ULL
+#define VSC_COMPILER_OPT_NO_LCP                         0x0000000400000000ULL
+#define VSC_COMPILER_OPT_NO_LCSE                        0x0000000800000000ULL
+#define VSC_COMPILER_OPT_NO_DCE                         0x0000001000000000ULL
+#define VSC_COMPILER_OPT_NO_PRE                         0x0000002000000000ULL
+#define VSC_COMPILER_OPT_NO_PEEPHOLE                    0x0000004000000000ULL
+#define VSC_COMPILER_OPT_NO_CONSTANT_PROPOGATION        0x0000008000000000ULL
+#define VSC_COMPILER_OPT_NO_CONSTANT_FOLDING            0x0000010000000000ULL
+#define VSC_COMPILER_OPT_NO_FUNC_INLINE                 0x0000020000000000ULL
+#define VSC_COMPILER_OPT_NO_INST_SKED                   0x0000040000000000ULL
+#define VSC_COMPILER_OPT_NO_GPR_SPILLABLE               0x0000080000000000ULL
+#define VSC_COMPILER_OPT_NO_CONSTANT_REG_SPILLABLE      0x0000100000000000ULL
+#define VSC_COMPILER_OPT_NO_VEC                         0x0000200000000000ULL /* Including logic io packing */
+#define VSC_COMPILER_OPT_NO_IO_PACKING                  0x0000400000000000ULL /* Physical io packing */
+#define VSC_COMPILER_OPT_NO_FULL_ACTIVE_IO              0x0000800000000000ULL
+#define VSC_COMPILER_OPT_NO_DUAL16                      0x0001000000000000ULL
+#define VSC_COMPILER_OPT_NO_ILF_LINK                    0x0002000000000000ULL
+
+#define VSC_COMPILER_OPT_NO_OPT                         0x0003FFFF00000000ULL
+
+/* Compiler flag for special purpose */
+#define VSC_COMPILER_FLAG_COMPILE_TO_HL                0x00000001   /* Compile IR to HL, including doing all opts in HL */
+#define VSC_COMPILER_FLAG_COMPILE_TO_ML                0x00000002   /* Compile IR to ML, including doing all opts in HL&ML */
+#define VSC_COMPILER_FLAG_COMPILE_TO_LL                0x00000004   /* Compile IR to LL, including doing all opts in HL&ML&LL */
+#define VSC_COMPILER_FLAG_COMPILE_TO_MC                0x00000008   /* Compile IR to MC, including doing all opts in all levels */
+#define VSC_COMPILER_FLAG_COMPILE_CODE_GEN             0x00000010
+#define VSC_COMPILER_FLAG_SEPERATED_SHADERS            0x00000020
+#define VSC_COMPILER_FLAG_UNI_UNIFORM_UNIFIED_ALLOC    0x00000040
+#define VSC_COMPILER_FLAG_UNI_SAMPLER_UNIFIED_ALLOC    0x00000080
+#define VSC_COMPILER_FLAG_UNI_UNIFORM_FIXED_BASE_ALLOC 0x00000100
+#define VSC_COMPILER_FLAG_UNI_SAMPLER_FIXED_BASE_ALLOC 0x00000200
+#define VSC_COMPILER_FLAG_NEED_OOB_CHECK               0x00000400
+#define VSC_COMPILER_FLAG_FLUSH_DENORM_TO_ZERO         0x00000800
+#define VSC_COMPILER_FLAG_WAVIER_RESLAYOUT_COMPATIBLE  0x00001000   /* Vulkan only for resource layout is provided */
+#define VSC_COMPILER_FLAG_NEED_RTNE_ROUNDING           0x00002000
+#define VSC_COMPILER_FLAG_API_UNIFORM_PRECISION_CHECK  0x00004000
+#define VSC_COMPILER_FLAG_LINK_PROGRAM_PIPELINE_OBJ    0x00008000
+#define VSC_COMPILER_FLAG_RECOMPILER                   0x00010000
+#define VSC_COMPILER_FLAG_USE_VSC_IMAGE_DESC           0x00020000
+#define VSC_COMPILER_FLAG_ENABLE_MULTI_GPU             0x00040000
+#define VSC_COMPILER_FLAG_DISABLE_IR_DUMP              0x00080000  /* used by driver to disable patch lib IR dump */
+
+#define VSC_COMPILER_FLAG_COMPILE_FULL_LEVELS          0x0000000F
+
+#define VSC_MAX_GFX_SHADER_STAGE_COUNT                 5
+#define VSC_MAX_CPT_SHADER_STAGE_COUNT                 1
+#define VSC_MAX_HW_PIPELINE_SHADER_STAGE_COUNT         VSC_MAX_GFX_SHADER_STAGE_COUNT
+#define VSC_MAX_LINKABLE_SHADER_STAGE_COUNT            VSC_MAX_HW_PIPELINE_SHADER_STAGE_COUNT
+#define VSC_MAX_SHADER_STAGE_COUNT                     (VSC_MAX_GFX_SHADER_STAGE_COUNT + VSC_MAX_CPT_SHADER_STAGE_COUNT)
+
+/* For indexing VSC_MAX_SHADER_STAGE_COUNT */
+#define VSC_SHADER_STAGE_VS                            0
+#define VSC_SHADER_STAGE_HS                            1
+#define VSC_SHADER_STAGE_DS                            2
+#define VSC_SHADER_STAGE_GS                            3
+#define VSC_SHADER_STAGE_PS                            4
+#define VSC_SHADER_STAGE_CS                            5
+
+/* This means stage (type) of shader is not known, and can not be directly flushed down
+   to HW. Normally, this shader might be a combination of several shader stage, or a
+   portion of a shader stage, or functional lib that might be linked to another shader.
+   So VSC_SHADER_STAGE_UNKNOWN is not counted by VSC_MAX_SHADER_STAGE_COUNT */
+#define VSC_SHADER_STAGE_UNKNOWN                       0xFF
+
+#define VSC_SHADER_STAGE_2_STAGE_BIT(shStage)          (1 << (shStage))
+
+typedef enum _VSC_SHADER_STAGE_BIT
+{
+    VSC_SHADER_STAGE_BIT_VS = VSC_SHADER_STAGE_2_STAGE_BIT(VSC_SHADER_STAGE_VS),
+    VSC_SHADER_STAGE_BIT_HS = VSC_SHADER_STAGE_2_STAGE_BIT(VSC_SHADER_STAGE_HS),
+    VSC_SHADER_STAGE_BIT_DS = VSC_SHADER_STAGE_2_STAGE_BIT(VSC_SHADER_STAGE_DS),
+    VSC_SHADER_STAGE_BIT_GS = VSC_SHADER_STAGE_2_STAGE_BIT(VSC_SHADER_STAGE_GS),
+    VSC_SHADER_STAGE_BIT_PS = VSC_SHADER_STAGE_2_STAGE_BIT(VSC_SHADER_STAGE_PS),
+    VSC_SHADER_STAGE_BIT_CS = VSC_SHADER_STAGE_2_STAGE_BIT(VSC_SHADER_STAGE_CS),
+}
+VSC_SHADER_STAGE_BIT;
+
+/* For indexing VSC_MAX_GFX_SHADER_STAGE_COUNT, VSC_MAX_HW_PIPELINE_SHADER_STAGE_COUNT
+   and VSC_MAX_LINKABLE_SHADER_STAGE_COUNT */
+#define VSC_GFX_SHADER_STAGE_VS                        VSC_SHADER_STAGE_VS
+#define VSC_GFX_SHADER_STAGE_HS                        VSC_SHADER_STAGE_HS
+#define VSC_GFX_SHADER_STAGE_DS                        VSC_SHADER_STAGE_DS
+#define VSC_GFX_SHADER_STAGE_GS                        VSC_SHADER_STAGE_GS
+#define VSC_GFX_SHADER_STAGE_PS                        VSC_SHADER_STAGE_PS
+#define VSC_CPT_SHADER_STAGE_CS                        0
+
+typedef void* SHADER_HANDLE;
+typedef void* VSC_PRIV_DATA_HANDLE;
+
+typedef enum _VSC_SHADER_RESOURCE_TYPE
+{
+    VSC_SHADER_RESOURCE_TYPE_SAMPLER                = 0, /* s#, sampler         */
+    VSC_SHADER_RESOURCE_TYPE_COMBINED_IMAGE_SAMPLER = 1, /* s#/t#, sampler2D       */
+    VSC_SHADER_RESOURCE_TYPE_SAMPLED_IMAGE          = 2, /* t#, texture2D       */
+    VSC_SHADER_RESOURCE_TYPE_STORAGE_IMAGE          = 3, /* u#, image2D         */
+    VSC_SHADER_RESOURCE_TYPE_UNIFORM_TEXEL_BUFFER   = 4, /* t#, samplerBuffer   */
+    VSC_SHADER_RESOURCE_TYPE_STORAGE_TEXEL_BUFFER   = 5, /* u#, imageBuffer     */
+    VSC_SHADER_RESOURCE_TYPE_UNIFORM_BUFFER         = 6, /* cb#, uniform 'block' */
+    VSC_SHADER_RESOURCE_TYPE_STORAGE_BUFFER         = 7, /* u#, buffer 'block'  */
+    VSC_SHADER_RESOURCE_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, /* cb#, uniform 'block' */
+    VSC_SHADER_RESOURCE_TYPE_STORAGE_BUFFER_DYNAMIC = 9, /* u#, buffer 'block'  */
+    VSC_SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT       = 10,/* t#, subpass         */
+} VSC_SHADER_RESOURCE_TYPE;
+
+typedef struct _VSC_SHADER_RESOURCE_BINDING
+{
+    VSC_SHADER_RESOURCE_TYPE          type;
+    gctUINT32                         set;        /* Set-No in pResourceSets array */
+    gctUINT32                         binding;
+    gctUINT32                         arraySize;  /* 1 means not an array */
+}VSC_SHADER_RESOURCE_BINDING;
+
+typedef struct _VSC_PROGRAM_RESOURCE_BINDING
+{
+    VSC_SHADER_RESOURCE_BINDING       shResBinding;
+    VSC_SHADER_STAGE_BIT              stageBits;  /* Which shader stages could access this resource */
+}VSC_PROGRAM_RESOURCE_BINDING;
+
+typedef struct _VSC_PROGRAM_RESOURCE_SET
+{
+    gctUINT32                         resourceBindingCount;
+    VSC_PROGRAM_RESOURCE_BINDING*     pResouceBindings;
+}VSC_PROGRAM_RESOURCE_SET;
+
+typedef struct _VSC_SHADER_PUSH_CONSTANT_RANGE
+{
+    gctUINT32                         offset;
+    gctUINT32                         size;
+} VSC_SHADER_PUSH_CONSTANT_RANGE;
+
+typedef struct _VSC_PROGRAM_PUSH_CONSTANT_RANGE
+{
+    VSC_SHADER_PUSH_CONSTANT_RANGE    shPushConstRange;
+    VSC_SHADER_STAGE_BIT              stageBits; /* Which shader stages could access this push-constant */
+} VSC_PROGRAM_PUSH_CONSTANT_RANGE;
+
+/* Resource layout */
+typedef struct _VSC_PROGRAM_RESOURCE_LAYOUT
+{
+    gctUINT32                         resourceSetCount; /* How many descritor set? */
+    VSC_PROGRAM_RESOURCE_SET*         pResourceSets;
+
+    gctUINT32                         pushConstantRangeCount;
+    VSC_PROGRAM_PUSH_CONSTANT_RANGE*  pPushConstantRanges;
+} VSC_PROGRAM_RESOURCE_LAYOUT;
+
+typedef struct _VSC_SHADER_RESOURCE_LAYOUT
+{
+    gctUINT32                         resourceBindingCount;
+    VSC_SHADER_RESOURCE_BINDING*      pResBindings;
+
+    gctUINT32                         pushConstantRangeCount;
+    VSC_SHADER_PUSH_CONSTANT_RANGE*   pPushConstantRanges;
+}VSC_SHADER_RESOURCE_LAYOUT;
+
+/* In general, a core system contex is maintained by driver's adapter/device who can
+   designate a GPU chip, which means core system contex is GPU wide global context. */
+typedef struct _VSC_CORE_SYS_CONTEXT
+{
+    /* Designates a target HW */
+    VSC_HW_CONFIG                     hwCfg;
+
+    /* VSC private data, maintained by vscCreatePrivateData and vscDestroyPrivateData */
+    VSC_PRIV_DATA_HANDLE              hPrivData;
+}VSC_CORE_SYS_CONTEXT, *PVSC_CORE_SYS_CONTEXT;
+
+/* A system context is combination of core system contex and driver callbacks which can
+   be driver context/device/... wide based on each driver's architecture */
+typedef struct _VSC_SYS_CONTEXT
+{
+    PVSC_CORE_SYS_CONTEXT             pCoreSysCtx;
+
+    /* Driver system callbacks. When VSC is fully decoupled with driver later,
+       no need this anymore. Note hDrv designates driver where callbacks are
+       called to and all callbacks' first param must be this hDrv */
+    DRIVER_HANDLE                     hDrv;
+    VSC_DRV_CALLBACKS                 drvCBs;
+}VSC_SYS_CONTEXT, *PVSC_SYS_CONTEXT;
+
+/* Lib-link inerface definitions */
+#include "gc_vsc_drvi_lib_link.h"
+
+/* Output profiles definitions */
+#include "gc_vsc_drvi_shader_priv_mapping.h"
+#include "gc_vsc_drvi_shader_profile.h"
+#include "gc_vsc_drvi_program_profile.h"
+#include "gc_vsc_drvi_kernel_profile.h"
+
+/* A context designate an enviroment where a shader is going to be compiled */
+typedef struct _VSC_CONTEXT
+{
+    /* Designate invoking client driver */
+    gceAPI                            clientAPI;
+    gcePATCH_ID                       appNameId;
+    gctBOOL                           isPatchLib;
+
+    /* System wide context */
+    PVSC_SYS_CONTEXT                  pSysCtx;
+}VSC_CONTEXT, *PVSC_CONTEXT;
+
+/* VSC compiler configuration */
+typedef struct _VSC_COMPILER_CONFIG
+{
+    VSC_CONTEXT                       ctx;
+
+    /* Compiler controls */
+    gctUINT                           cFlags;
+    gctUINT64                         optFlags;
+}VSC_COMPILER_CONFIG, *PVSC_COMPILER_CONFIG;
+
+/* Shader compiler parameter for VSC compiler entrance. */
+typedef struct _VSC_SHADER_COMPILER_PARAM
+{
+    VSC_COMPILER_CONFIG               cfg;
+
+    SHADER_HANDLE                     hShader;
+    VSC_SHADER_RESOURCE_LAYOUT*       pShResourceLayout; /* Vulkan ONLY */
+
+    /* For static compilation, when it is set (as static lib), pInMasterSEP must
+       be set to NULL and hShader should be the original shader.
+
+       For recompilaton, when it is set (as dynamic lib), pInMasterSEP must NOT be
+       set to NULL and hShader should be the combination of original shader and static
+       lib passed in when static compilation */
+    VSC_SHADER_LIB_LINK_TABLE*        pShLibLinkTable;
+
+    SHADER_EXECUTABLE_PROFILE*        pInMasterSEP; /* For recompilation ONLY */
+}VSC_SHADER_COMPILER_PARAM, *PVSC_SHADER_COMPILER_PARAM;
+
+/* Program linker parameter for VSC linker entrance. */
+typedef struct _VSC_PROGRAM_LINKER_PARAM
+{
+    VSC_COMPILER_CONFIG               cfg;
+    PVSC_GL_API_CONFIG                pGlApiCfg;
+
+    SHADER_HANDLE                     hShaderArray[VSC_MAX_SHADER_STAGE_COUNT];
+    VSC_PROGRAM_RESOURCE_LAYOUT*      pPgResourceLayout; /* Vulkan ONLY */
+
+    /* See comment of pShLibLinkTable in VSC_SHADER_COMPILER_PARAM */
+    VSC_PROG_LIB_LINK_TABLE*          pProgLibLinkTable;
+
+    PROGRAM_EXECUTABLE_PROFILE*       pInMasterPEP; /* For recompilation ONLY */
+}VSC_PROGRAM_LINKER_PARAM, *PVSC_PROGRAM_LINKER_PARAM;
+
+/* Kernel program linker parameter for VSC linker entrance. */
+typedef struct VSC_KERNEL_PROGRAM_LINKER_PARAM
+{
+    VSC_COMPILER_CONFIG               cfg;
+
+    SHADER_HANDLE*                    pKrnlModuleHandlesArray;
+    gctUINT                           moduleCount;
+
+    /* See comment of pShLibLinkTable in VSC_SHADER_COMPILER_PARAM */
+    VSC_SHADER_LIB_LINK_TABLE*        pShLibLinkTable;
+
+    KERNEL_EXECUTABLE_PROFILE**       ppInMasterKEPArray; /* For recompilation ONLY */
+}VSC_KERNEL_PROGRAM_LINKER_PARAM, *PVSC_KERNEL_PROGRAM_LINKER_PARAM;
+
+/* HW pipeline shaders linker parameter */
+typedef struct _VSC_HW_PIPELINE_SHADERS_PARAM
+{
+    PVSC_SYS_CONTEXT                  pSysCtx;
+
+    SHADER_EXECUTABLE_PROFILE*        pSEPArray[VSC_MAX_HW_PIPELINE_SHADER_STAGE_COUNT];
+}VSC_HW_PIPELINE_SHADERS_PARAM, *PVSC_HW_PIPELINE_SHADERS_PARAM;
+
+/* Returned HW linker info which will be used for states programming */
+typedef struct _VSC_HW_SHADERS_LINK_INFO
+{
+    SHADER_HW_INFO                    shHwInfoArray[VSC_MAX_HW_PIPELINE_SHADER_STAGE_COUNT];
+}VSC_HW_SHADERS_LINK_INFO, *PVSC_HW_SHADERS_LINK_INFO;
+
+/* A state buffer that hold all shaders programming for GPU kickoff */
+typedef struct _VSC_HW_PIPELINE_SHADERS_STATES
+{
+    gctUINT32                         stateBufferSize;
+    void*                             pStateBuffer;
+
+    /* It is DEPRECATED if driver directly uses EPs (PEP/KEP/SEP) as all
+       the info stored in hints can be retrieved by SEP */
+    struct _gcsHINT                   hints;
+
+    gcsPROGRAM_VidMemPatchOffset      patchOffsetsInDW;
+    gctUINT32                         stateDeltaSize;
+    gctUINT32*                        pStateDelta;
+
+}VSC_HW_PIPELINE_SHADERS_STATES, *PVSC_HW_PIPELINE_SHADERS_STATES;
+
+gceSTATUS vscInitializeHwPipelineShadersStates(VSC_SYS_CONTEXT* pSysCtx, VSC_HW_PIPELINE_SHADERS_STATES* pHwShdsStates);
+gceSTATUS vscFinalizeHwPipelineShadersStates(VSC_SYS_CONTEXT* pSysCtx, VSC_HW_PIPELINE_SHADERS_STATES* pHwShdsStates);
+
+/* VSC private data creater/destroyer, every client should call it at least at
+   driver device granularity  */
+gceSTATUS vscCreatePrivateData(VSC_CORE_SYS_CONTEXT* pCoreSysCtx, VSC_PRIV_DATA_HANDLE* phOutPrivData, gctBOOL bForOCL);
+gceSTATUS vscDestroyPrivateData(VSC_CORE_SYS_CONTEXT* pCoreSysCtx, VSC_PRIV_DATA_HANDLE hPrivData);
+
+/* Create a shader with content unfilled. In general, driver calls this
+   function to create a shader, and then pass this shader handle to shader
+   generator. Or alternatively, shader generator can directly call this
+   function to create a shader in mem inside and return it to driver, then
+   driver dont need call it. To all these two cases, driver must call
+   vscDestroyShader when driver does not need it. */
+gceSTATUS vscCreateShader(SHADER_HANDLE* pShaderHandle,
+                          gctUINT shStage);
+gceSTATUS vscDestroyShader(SHADER_HANDLE hShader);
+
+/* Print (dump) shader */
+gceSTATUS vscPrintShader(SHADER_HANDLE hShader,
+                         gctFILE hFile,
+                         gctCONST_STRING strHeaderMsg,
+                         gctBOOL bPrintHeaderFooter);
+
+/* Shader binary saver and loader */
+
+/* vscSaveShaderToBinary()
+ * Two ways to save shader binary:
+ * 1) compiler allocates memory and return the memory in *pBinary and size in pSizeInByte
+ *    if (* pBinary) is NULL when calling the function
+ * 2) user query the shader binary size with vscQueryShaderBinarySize() and allocate
+ *    memory in (*pBinary), size in pSizeInByte
+ */
+gceSTATUS vscSaveShaderToBinary(SHADER_HANDLE hShader,
+                                void**        pBinary,
+                                gctUINT*      pSizeInByte);
+/* vscLoadShaderFromBinary()
+ * restore shader from pBinary which should be serialized by vscSaveShaderToBinary()
+ * if bFreeBinary is true, pBinary is deallocated by this function
+ */
+gceSTATUS vscLoadShaderFromBinary(void*          pBinary,
+                                  gctUINT        sizeInByte,
+                                  SHADER_HANDLE* pShaderHandle,
+                                  gctBOOL        bFreeBinary);
+
+/* Free the vir intrinsic library. */
+gceSTATUS vscFreeVirIntrinsicLib(void);
+
+gceSTATUS vscQueryShaderBinarySize(SHADER_HANDLE hShader, gctUINT* pSizeInByte);
+
+gctPOINTER vscGetDebugInfo(IN SHADER_HANDLE    Shader);
+gctPOINTER vscDupDebugInfo(IN SHADER_HANDLE    Shader);
+gceSTATUS  vscDestroyDebugInfo(IN gctPOINTER DebugInfo);
+
+/* Shader copy */
+gceSTATUS vscCopyShader(SHADER_HANDLE * hToShader, SHADER_HANDLE hFromShader);
+
+/* It will extract a specific sub-shader from main shader. It will be mainly used by CL to pick specific kernel
+   from kernel program. */
+gceSTATUS vscExtractSubShader(SHADER_HANDLE   hMainShader,
+                              gctCONST_STRING pSubShaderEntryName,
+                              SHADER_HANDLE   hSubShader);
+
+gcSHADER_KIND vscGetShaderKindFromShaderHandle(SHADER_HANDLE hShader);
+
+/* Link a lib shader to main shader. */
+gceSTATUS vscLinkLibShaderToShader(SHADER_HANDLE              hMainShader,
+                                   VSC_SHADER_LIB_LINK_TABLE* pShLibLinkTable);
+
+/* DX/CL driver will call this directly, GL will call this directly after FE
+   or inside of vscLinkProgram. After successfully shader compilation, a SEP
+   may be generated based on cFlags */
+gceSTATUS vscCompileShader(VSC_SHADER_COMPILER_PARAM* pCompilerParam,
+                           SHADER_EXECUTABLE_PROFILE* pOutSEP /* Caller should destory the mem,
+                                                                 so dont use VSC MM to allocate
+                                                                 inside of VSC. */
+                          );
+
+/* GL/Vulkan driver ONLY interface, this is HL interface to match glLinkProgram
+   API. It may call vscCompileShader for each shader inside. After successfully
+   program linking, a PEP will be generated. Also program states will auto be
+   generated at this time if driver request. If not, driver may want program
+   states by itself.  */
+gceSTATUS vscLinkProgram(VSC_PROGRAM_LINKER_PARAM*       pPgLinkParam,
+                         PROGRAM_EXECUTABLE_PROFILE*     pOutPEP, /* Caller should destory the mem, */
+                         VSC_HW_PIPELINE_SHADERS_STATES* pOutPgStates /* so for these two, dont use VSC
+                                                                         MM to allocate inside of VSC. */
+                        );
+
+/* CL driver ONLY interface, this is HL interface to match clCreateKernel API
+   if clBuildProgram does not directly generate MC, or to be called inside of
+   vscLinkKernelProgram matched with clLinkProgram/clBuildProgram if it want
+   to directly generate MC. It will call vscCompileShader inside. After succ-
+   essfully creating, a KEP will be generated. Also kernel states will auto be
+   generated at this time if driver request. If not, driver may want program
+   states by itself. */
+gceSTATUS vscCreateKernel(VSC_SHADER_COMPILER_PARAM*      pCompilerParam,
+                          KERNEL_EXECUTABLE_PROFILE*      pOutKEP, /* Caller should destory the mem, */
+                          VSC_HW_PIPELINE_SHADERS_STATES* pOutKrnlStates /* so for these two, dont use VSC
+                                                                            MM to allocate inside of VSC. */
+                         );
+
+/* CL driver ONLY interface, this is HL interface to match clLinkProgram or
+   clBuildProgram API. It will call vscCreateKernel inside. After successfully
+   creating, a KEP list will be generated to match each kernel. Also kernel
+   states array matched each kernel will auto be generated at this time
+   if driver request. If not, driver may want program states by itself. */
+gceSTATUS vscLinkKernelProgram(VSC_KERNEL_PROGRAM_LINKER_PARAM*  pKrnlPgLinkParam,
+                               gctUINT*                          pKernelCount,
+                               SHADER_HANDLE                     hOutLinkedProgram,
+                               KERNEL_EXECUTABLE_PROFILE**       ppOutKEPArray, /* Caller should destory the mem, */
+                               VSC_HW_PIPELINE_SHADERS_STATES**  ppOutKrnlStates      /* so for these two, dont use VSC
+                                                                                         MM to allocate inside of VSC. */
+                              );
+
+/* This is hw level link that every client should call before programming */
+gceSTATUS vscLinkHwShaders(VSC_HW_PIPELINE_SHADERS_PARAM*  pHwPipelineShsParam,
+                           VSC_HW_SHADERS_LINK_INFO*       pOutHwShdsLinkInfo,
+                           gctBOOL                         bSeperatedShaders);
+
+/* All clients can call this function when drawing/dispatching/kickoffing to program
+   shaders stages that current pipeline uses to launch GPU task in cores. For example,
+   driver may send program-pipeline which holds all shaders that pipeline needs to ask
+   for programming. After success, hw pipeline shaders states will be generated. If
+   driver want do program by itself, then it wont be called. */
+gceSTATUS vscProgramHwShaderStages(VSC_HW_PIPELINE_SHADERS_PARAM*   pHwPipelineShsParam,
+                                   VSC_HW_PIPELINE_SHADERS_STATES*  pOutHwShdsStates, /* Caller should destory the mem,
+                                                                                           so dont use VSC MM to allocate
+                                                                                           inside of VSC. */
+                                   gctBOOL                          bSeperatedShaders   /* It is a temporary fix,
+                                                                                           we need to remove it later. */
+                                  );
+
+/****************************************************************************
+   Following are for future EP, including SEP, KEP and PEP.
+*****************************************************************************/
+typedef enum _VSC_EP_KIND
+{
+    VSC_EP_KIND_NONE            = 0,
+    /* Shader executable profile. */
+    VSC_EP_KIND_SHADER          = 1,
+    /* Kernel executable profile. */
+    VSC_EP_KIND_KERNEL          = 2,
+    /* Program executable profile. */
+    VSC_EP_KIND_PROGRAM         = 3,
+}VSC_EP_KIND;
+
+/* For saver, it always returns how many bytes it saves to binary buffer, and
+              1). if ppOutBinary == NULL (szBinaryInByte will be igored), then not doing real saving, just return byte size
+              2). if ppOutBinary != NULL and *ppOutBinary == NULL (szBinaryInByte will be igored), then saver will allocate a
+                  binary for user.
+              3). *ppOutBinary != NULL, then szBinaryInByte must be the size of the binary (generally, this size got by first usage
+                  of this function).
+   For loader, szBinaryInByte must be size of binary, and return value is the real sparsed size of binary. */
+gctUINT vscSaveEPToBinary(VSC_EP_KIND epKind, void* pEP, void** ppOutBinary, gctUINT szBinaryInByte);
+gctUINT vscLoadEPFromBinary(VSC_EP_KIND epKind, void* pInBinary, gctUINT szBinaryInByte, void* pEP);
+
+/****************************************************************************
+   Following are for future MC level recompiling. Right now, we are using HL
+   recompiling, so these are not used now.
+*****************************************************************************/
+
+/* VSC recompiler configuration */
+typedef struct _VSC_RECOMPILER_CONFIG
+{
+    VSC_CONTEXT                       ctx;
+
+    /* Recompiler controls */
+    gctUINT                           rcFlags;
+}VSC_RECOMPILER_CONFIG, *PVSC_RECOMPILER_CONFIG;
+
+/* Shader recompiler parameter for VSC recompiler entrance. */
+typedef struct _VSC_SHADER_RECOMPILER_PARAM
+{
+    VSC_RECOMPILER_CONFIG             cfg;
+}VSC_SHADER_RECOMPILER_PARAM, *PVSC_SHADER_RECOMPILER_PARAM;
+
+gceSTATUS
+vscConvertGcShader2VirShader(
+    IN  SHADER_HANDLE           GcShader,
+    OUT SHADER_HANDLE*          phVirShader
+    );
+
+/* For given image descriptor and sampler value for HW cfg, do we
+ * need to do recompilation for the image read ? */
+gctBOOL
+vscImageSamplerNeedLibFuncForHWCfg(
+    void *                  pImageDesc,
+    gctUINT                 ImageSamplerValue,
+    VSC_HW_CONFIG *         pHwCfg,
+    VSC_OCLImgLibKind *     pImgLibKind, /* the image lib kind to be used */
+    gctBOOL *               UseTexld, /* set true if need to use texld for image_read */
+    gctUINT *               KeyofImgSampler         /* the key state of the image-sampler pair */
+    );
+
+/* For given image descriptorfor HW cfg, do we
+ * need to do recompilation for the image write ?  */
+gctBOOL
+vscImageWriteNeedLibFuncForHWCfg(
+    void *                  pImageDesc,
+    VSC_HW_CONFIG *         pHwCfg,
+    VSC_OCLImgLibKind *     pImgLibKind, /* the image lib kind to be used */
+    gctUINT *               KeyofImgSampler
+    );
+
+gceSTATUS
+vscConstructImageReadLibFuncName(
+    VSC_ImageDesc *         ImageDescHandle, /* VSC_ImageDesc */
+    gctUINT                 SamplerValue, /* VSC_SamplerValue */
+    VSC_HW_CONFIG *         pHwCfg,
+    gctSTRING *             pLibFuncName, /* returned lib function name if needed */
+    VSC_OCLImgLibKind *     pImgLibKind, /* the image lib kind to be used */
+    gctBOOL *               UseTexld                /* set true if need to use texld for image_read */
+    );
+
+gceSTATUS
+vscConstructImageWriteLibFuncName(
+    VSC_ImageDesc *         ImageDescHandle, /* VSC_ImageDesc */
+    VSC_HW_CONFIG *         pHwCfg,
+    gctSTRING *             pLibFuncName, /* returned lib function name if needed */
+    VSC_OCLImgLibKind *     pImgLibKind             /* the image lib kind to be used */
+);
+
+VSC_OCLImgLibKind vscGetOCLImgLibKindForHWCfg(
+    IN VSC_HW_CONFIG            *pHwCfg
+    );
+
+/* Return the max free reg count for this HW config. */
+gctUINT
+vscGetHWMaxFreeRegCount(
+    IN VSC_HW_CONFIG   *pHwCfg
+    );
+
+gceSTATUS
+gcSHADER_WriteBufferToFile(
+    IN gctSTRING buffer,
+    IN gctUINT32 bufferSize,
+    IN gctSTRING ShaderName
+    );
+
+gceSTATUS
+gcSHADER_ReadBufferFromFile(
+    IN gctSTRING    ShaderName,
+    OUT gctSTRING    *buf,
+    OUT gctUINT *bufSize
+    );
+
+void vscSetDriverVIRPath(gctBOOL bUseVIRPath);
+
+gceSTATUS vscGetTemporaryDir(OUT gctSTRING gcTmpDir);
+
+void vscSetIsLibraryShader(SHADER_HANDLE hShader, gctBOOL bIsLibraryShader);
+
+END_EXTERN_C();
+
+#endif /*__gc_vsc_drvi_interface_h_ */
+
+
diff --git a/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_kernel_profile.h b/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_kernel_profile.h
new file mode 100644 (file)
index 0000000..5ec89db
--- /dev/null
@@ -0,0 +1,208 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+/*********************************************************************************
+   Following definitions are ONLY used for openCL(ES) to communicate with client
+   query/binding request from kernel. NOTE that ONLY active parts are collected
+   into each high level table.
+**********************************************************************************/
+
+#ifndef __gc_vsc_drvi_kernel_profile_h_
+#define __gc_vsc_drvi_kernel_profile_h_
+
+BEGIN_EXTERN_C()
+
+#define VIR_CL_INVALID_ARG_INDEX               0xffffffff
+
+typedef struct PROG_CL_UNIFORM_COMMON_ENTRY
+{
+    gctCONST_STRING                             name;
+    gctUINT                                     nameLength;
+    gctBOOL                                     pointer;
+
+    SHADER_CONSTANT_SUB_ARRAY_MAPPING *         hwMapping;
+    /*SHADER_CONSTANT_ARRAY_MAPPING *             hwMapping;*/
+}
+PROG_CL_UNIFORM_COMMON_ENTRY;
+
+typedef struct PROG_CL_UNIFORM_TABLE_ENTRY
+{
+    gctUINT                                     argIndex;
+
+    PROG_CL_UNIFORM_COMMON_ENTRY                common;
+}
+PROG_CL_UNIFORM_TABLE_ENTRY;
+
+typedef struct PROG_CL_UNIFORM_TABLE
+{
+    PROG_CL_UNIFORM_TABLE_ENTRY*                pUniformEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_CL_UNIFORM_TABLE;
+
+typedef struct PROG_CL_PRV_UNIFORM_COMMON_ENTRY
+{
+    gctCONST_STRING                             name;
+    gctUINT                                     nameLength;
+
+    SHADER_PRIV_CONSTANT_ENTRY *                hwMapping;
+}
+PROG_CL_PRV_UNIFORM_COMMON_ENTRY;
+
+typedef struct PROG_CL_PRV_UNIFORM_TABLE
+{
+    PROG_CL_PRV_UNIFORM_COMMON_ENTRY*           pUniformEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_CL_PRV_UNIFORM_TABLE;
+
+typedef struct PROG_CL_COMBINED_TEXTURE_SAMPLER_HW_MAPPING
+{
+    /* For the case
+       1. HW natively supports separated sampler, so sampler part of API combined texture
+          sampler will be directly mapped to HW separated sampler
+       2. HW does not natively support separated sampler, so API combined texture sampler
+          is directly mapped to HW combined sampler */
+    SHADER_SAMPLER_SLOT_MAPPING                 samplerMapping;
+
+    /* For the case that HW natively supports separated texture, so texture part of API
+       combined texture sampler will be directly mapped to HW separated texture */
+    SHADER_RESOURCE_SLOT_MAPPING                texMapping;
+
+}PROG_CL_COMBINED_TEXTURE_SAMPLER_HW_MAPPING;
+
+/* TO_DO, image array and sampler array */
+typedef struct PROG_CL_COMBINED_TEX_SAMPLER_TABLE_ENTRY
+{
+    gctUINT                                    imageArgIndex;
+
+    gctBOOL                                    kernelHardcodeSampler;
+    gctUINT                                    samplerArgIndex;
+    gctUINT                                    constSamplerValue;
+
+    PROG_CL_COMBINED_TEXTURE_SAMPLER_HW_MAPPING * hwMappings;
+}
+PROG_CL_COMBINED_TEX_SAMPLER_TABLE_ENTRY;
+
+
+typedef struct PROG_CL_COMBINED_TEXTURE_SAMPLER_TABLE
+{
+    PROG_CL_COMBINED_TEX_SAMPLER_TABLE_ENTRY*   pCombTsEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_CL_COMBINED_TEXTURE_SAMPLER_TABLE;
+
+typedef struct PROG_CL_IMAGE_TABLE_ENTRY
+{
+    gctUINT                                    imageArgIndex;
+
+    gctBOOL                                    kernelHardcodeSampler;
+    gctUINT                                    samplerArgIndex;
+    gctUINT                                    constSamplerValue;
+
+    SHADER_CONSTANT_SUB_ARRAY_MAPPING *        hwMapping;
+    VSC_ImageDesc                              imageDesc; /*the assumed value of image descriptor by compiler*/
+    gctUINT                                    assumedSamplerValue; /*the assumed value of sampler by compiler*/
+    /*SHADER_CONSTANT_ARRAY_MAPPING *            hwMapping;*/
+}
+PROG_CL_IMAGE_TABLE_ENTRY;
+
+typedef struct PROG_CL_IMAGE_TABLE
+{
+    PROG_CL_IMAGE_TABLE_ENTRY*                  pImageEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_CL_IMAGE_TABLE;
+
+/* Resource set */
+typedef struct PROG_CL_RESOURCE_TABLE
+{
+    /* For texLd */
+    PROG_CL_COMBINED_TEXTURE_SAMPLER_TABLE      combinedSampTexTable;
+    /* For image */
+    PROG_CL_IMAGE_TABLE                         imageTable;
+    /* For other uniform include private???*/
+    PROG_CL_UNIFORM_TABLE                       uniformTable;
+    /* private uniform table */
+    PROG_CL_PRV_UNIFORM_TABLE                   prvUniformTable;
+}
+PROG_CL_RESOURCE_TABLE;
+
+typedef struct PROG_CL_ARG_ENTRY
+{
+    gctUINT                                     argIndex;
+    gctBOOL                                     isImage;
+    gctBOOL                                     isSampler;
+    gctBOOL                                     isPointer;
+    VSC_SHADER_DATA_TYPE                        type;
+    /* for none basic type, VIR need have a name pool like GetUniformTypeNameOffset() */
+    gctINT                                      typeNameOffset;
+    gctUINT                                     addressQualifier;
+    gctUINT                                     typeQualifier;
+    gctUINT                                     accessQualifier;
+    gctSTRING                                   argName;
+    gctSTRING                                   argTypeName;
+}PROG_CL_ARG_ENTRY;
+
+typedef struct PROG_CL_ARG_TABLE
+{
+    gctUINT                                     countOfEntries;
+    PROG_CL_ARG_ENTRY *                         pArgsEntries;
+}PROG_CL_ARG_TABLE;
+
+typedef struct KERNEL_FUNCTIN_PROPERTY
+{
+    gctUINT                                     type;
+    gctUINT                                     size;
+    gctUINT                                     value[3];
+}KERNEL_FUNCTIN_PROPERTY;
+
+typedef struct KERNEL_FUNCTION_HINTS
+{
+    gctBOOL                                     hasPrintf;
+    gctUINT                                     imageCount;
+    gctUINT                                     samplerCount;
+    /* req work group size/ work group size hint/scalar hint */
+    KERNEL_FUNCTIN_PROPERTY                     property[3];
+
+    gctUINT32                                   privateMemorySize;
+    gctUINT32                                   localMemorySize;
+    gctUINT32                                   constantMemorySize;
+    gctCHAR *                                   constantMemBuffer;
+}KERNEL_FUNCTION_HINTS;
+
+/* Executable kernel profile definition. It is generated only when clCreateKernel calling.
+   Each client kernel only has one profile like this. */
+typedef struct KERNEL_EXECUTABLE_PROFILE
+{
+    /* The shaders that this kernel contains. */
+    SHADER_EXECUTABLE_PROFILE                   sep;
+
+    /* hint and other attribte of this kernel */
+    KERNEL_FUNCTION_HINTS                       kernelHints;
+
+    /* origin kernel arg table, include info that driver need */
+    PROG_CL_ARG_TABLE                           argTable;
+
+    PROG_CL_RESOURCE_TABLE                      resourceTable;
+}
+KERNEL_EXECUTABLE_PROFILE;
+
+gceSTATUS vscInitializeKEP(KERNEL_EXECUTABLE_PROFILE* pKEP);
+gceSTATUS vscFinalizeKEP(KERNEL_EXECUTABLE_PROFILE* pKEP);
+
+END_EXTERN_C();
+
+#endif /* __gc_vsc_drvi_kernel_profile_h_ */
+
+
diff --git a/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_lib_link.h b/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_lib_link.h
new file mode 100644 (file)
index 0000000..49b873e
--- /dev/null
@@ -0,0 +1,240 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_vsc_drvi_lib_link_h_
+#define __gc_vsc_drvi_lib_link_h_
+
+BEGIN_EXTERN_C()
+
+typedef union _SPECIALIZATION_CONSTANT_VALUE
+{
+    gctFLOAT                          fValue[4];
+    gctUINT                           uValue[4];
+    gctINT                            iValue[4];
+}SPECIALIZATION_CONSTANT_VALUE;
+
+typedef struct _VSC_LIB_SPECIALIZATION_CONSTANT
+{
+    gctCONST_STRING                   varName;
+    SPECIALIZATION_CONSTANT_VALUE     value;
+    VSC_SHADER_DATA_TYPE              type;
+}VSC_LIB_SPECIALIZATION_CONSTANT;
+
+/* Copy from VIR_ShLevel. */
+/* Any modification here, please do the corresponding change for VIR_ShLevel. */
+typedef enum _VSC_SH_LEVEL
+{
+    VSC_SHLEVEL_Unknown         = 0,
+
+    VSC_SHLEVEL_Pre_High        = 1,
+    VSC_SHLEVEL_Post_High       = 2,
+
+    VSC_SHLEVEL_Pre_Medium      = 3,
+    VSC_SHLEVEL_Post_Medium     = 4,
+
+    VSC_SHLEVEL_Pre_Low         = 5,
+    VSC_SHLEVEL_Post_Low        = 6,
+
+    VSC_SHLEVEL_Pre_Machine     = 7,
+    VSC_SHLEVEL_Post_Machine    = 8,
+    VSC_SHLEVEL_COUNT           = 9,
+} VSC_SH_LEVEL;
+
+typedef enum _VSC_LIB_LINK_TYPE
+{
+    /* A general lib link at call site function */
+    VSC_LIB_LINK_TYPE_FUNC_NAME                     = 0,
+
+    /*********************************************
+        Following are special link points
+     *********************************************/
+
+    /* Frag-output color */
+    VSC_LIB_LINK_TYPE_COLOR_OUTPUT                  = 1,
+
+    /* Resource access from shader */
+    VSC_LIB_LINK_TYPE_RESOURCE                      = 2,
+
+    /* frontfacing is counter clockwise, make to NOT Facing
+     * value to make HW happy */
+    VSC_LIB_LINK_TYPE_FRONTFACING_CCW               = 3,
+
+    /*
+    ** For non-polygon primitive, the value of gl_FrontFacing should be always TRUE,
+    ** but for some cases HW can't meet this requirement, so compiler forces change it to TRUE.
+    */
+    VSC_LIB_LINK_TYPE_FRONTFACING_ALWAY_FRONT       = 4,
+    /* image read/write need to use library function to implement
+     * the function for given <image, sampler> pair for read,
+     * image for write */
+    VSC_LIB_LINK_TYPE_IMAGE_READ_WRITE              = 5,
+
+    /* Image format. */
+    VSC_LIB_LINK_TYPE_IMAGE_FORMAT                  = 6,
+}VSC_LIB_LINK_TYPE;
+
+typedef enum _VSC_RES_OP_BIT
+{
+    VSC_RES_OP_BIT_TEXLD            = 0x00000001,
+    VSC_RES_OP_BIT_TEXLD_BIAS       = 0x00000002,
+    VSC_RES_OP_BIT_TEXLD_LOD        = 0x00000004,
+    VSC_RES_OP_BIT_TEXLD_GRAD       = 0x00000008,
+    VSC_RES_OP_BIT_TEXLDP           = 0x00000010,
+    VSC_RES_OP_BIT_TEXLDP_GRAD      = 0x00000020,
+    VSC_RES_OP_BIT_TEXLDP_BIAS      = 0x00000040,
+    VSC_RES_OP_BIT_TEXLDP_LOD       = 0x00000080,
+    VSC_RES_OP_BIT_FETCH            = 0x00000100,
+    VSC_RES_OP_BIT_FETCH_MS         = 0x00000200,
+    VSC_RES_OP_BIT_GATHER           = 0x00000400,
+    VSC_RES_OP_BIT_GATHER_PCF       = 0x00000800,
+    VSC_RES_OP_BIT_LODQ             = 0x00001000,
+    VSC_RES_OP_BIT_TEXLD_PCF        = 0x00002000,
+    VSC_RES_OP_BIT_TEXLD_BIAS_PCF   = 0x00004000,
+    VSC_RES_OP_BIT_TEXLD_LOD_PCF    = 0x00008000,
+    VSC_RES_OP_BIT_LOAD_STORE       = 0x00010000,
+    VSC_RES_OP_BIT_IMAGE_OP         = 0x00020000,
+    VSC_RES_OP_BIT_ATOMIC           = 0x00040000,
+}VSC_RES_OP_BIT;
+
+typedef enum _VSC_RES_ACT_BIT
+{
+    VSC_RES_ACT_BIT_EXTRA_SAMPLER                      = 0x0001,
+    VSC_RES_ACT_BIT_REPLACE_SAMPLER_WITH_IMAGE_UNIFORM = 0x0002,
+}VSC_RES_ACT_BIT;
+
+typedef enum _VSC_LINK_POINT_RESOURCE_SUBTYPE
+{
+    VSC_LINK_POINT_RESOURCE_SUBTYPE_TEXLD_EXTRA_LATYER              = 1,
+    VSC_LINK_POINT_RESOURCE_SUBTYPE_TEXGRAD_EXTRA_LATYER            = 2,
+    VSC_LINK_POINT_RESOURCE_SUBTYPE_TEXFETCH_REPLACE_WITH_IMGLD     = 3,
+    VSC_LINK_POINT_RESOURCE_SUBTYPE_TEXGATHER_EXTRA_LAYTER          = 4,
+    VSC_LINK_POINT_RESOURCE_SUBTYPE_TEXGATHERPCF_D32F               = 5,
+    VSC_LINK_POINT_RESOURCE_SUBTYPE_NORMALIZE_TEXCOORD              = 6,
+} VSC_LINK_POINT_RESOURCE_SUBTYPE;
+
+typedef struct _VSC_LIB_LINK_POINT_FUNC_NAME
+{
+    gctCONST_STRING                   funcName;
+}VSC_LIB_LINK_POINT_FUNC_NAME;
+
+typedef struct _VSC_LIB_LINK_POINT_CLR_OUTPUT
+{
+    gctINT                            location;
+    gctUINT                           layers;
+}VSC_LIB_LINK_POINT_CLR_OUTPUT;
+
+typedef struct _VSC_LIB_LINK_POINT_RESOURCE
+{
+    gctUINT                           set;
+    gctUINT                           binding;
+    gctUINT                           arrayIndex;
+    VSC_RES_OP_BIT                    opTypeBits;
+    VSC_RES_ACT_BIT                   actBits;
+    VSC_LINK_POINT_RESOURCE_SUBTYPE   subType;
+} VSC_LIB_LINK_POINT_RESOURCE;
+
+typedef struct _VSC_IMAGE_DESC_INFO
+{
+    gctINT                          kernelArgNo;    /* kernel arg number for the image */
+    VSC_ImageDesc                   imageDesc;      /* image descriptor value */
+    gctCONST_STRING                 name;           /* image variable name */
+} VSC_IMAGE_DESC_INFO;
+
+typedef struct _VSC_SAMPLER_INFO
+{
+    gctINT                          kernelArgNo;    /* kernel arg number for the sampler */
+    VSC_SamplerValue                sampleValue;    /* sampler descriptor value */
+    gctCONST_STRING                 name;           /* sampler variable name */
+} VSC_SAMPLER_INFO;
+
+typedef struct _VSC_LIB_LINK_IMAGE_READ_WRITE
+{
+    gctUINT                         imageCount;
+    VSC_IMAGE_DESC_INFO *           imageInfo;
+    gctUINT                         samplerCount;
+    VSC_SAMPLER_INFO *              samplerInfo;
+} VSC_LIB_LINK_IMAGE_READ_WRITE;
+
+typedef struct _VSC_LIB_LINK_IMAGE_FORMAT
+{
+    gctUINT                         set;
+    gctUINT                         binding;
+    gctUINT                         arrayIndex;
+    VSC_IMAGE_FORMAT                imageFormat;
+} VSC_LIB_LINK_IMAGE_FORMAT;
+
+typedef struct _VSC_LIB_LINK_POINT
+{
+    VSC_LIB_LINK_TYPE                 libLinkType;
+    gctBOOL                           linkImageIntrinsic;    /* do not link image lib functions if false */
+
+    /* The interested function maitained by lib shader. NOTE only the interested function
+       will be truely linked into main shader at each link point. If this function is NULL,
+       then it means all functions in lib might be linked into main shader */
+    gctCONST_STRING                   strFunc;
+
+    /* Where the function in lib shader will be linked in main shader */
+    union
+    {
+        VSC_LIB_LINK_POINT_FUNC_NAME  funcName;
+        VSC_LIB_LINK_POINT_CLR_OUTPUT clrOutput;
+        VSC_LIB_LINK_POINT_RESOURCE   resource;
+        VSC_LIB_LINK_IMAGE_READ_WRITE imageReadWrite;
+        VSC_LIB_LINK_IMAGE_FORMAT     imageFormat;
+    } u;
+}VSC_LIB_LINK_POINT;
+
+typedef struct _VSC_SHADER_LIB_LINK_ENTRY
+{
+    /* Which level this link entry should be applied. */
+    VSC_SH_LEVEL                      applyLevel;
+
+    /* Lib shader */
+    SHADER_HANDLE                     hShaderLib;
+
+    /* vreg map from libShader to the current shader */
+    void*                             pTempHashTable;
+
+    /* Some variables in function of lib will be determined when function of lib is linking */
+    gctUINT                           libSpecializationConstantCount;
+    VSC_LIB_SPECIALIZATION_CONSTANT*  pLibSpecializationConsts;
+
+    /* List of link points which designate where the function in lib-shader will be linked
+       into main shader. */
+    gctUINT                           linkPointCount;
+    VSC_LIB_LINK_POINT                linkPoint[1];
+}VSC_SHADER_LIB_LINK_ENTRY;
+
+typedef struct _VSC_PROG_LIB_LINK_ENTRY
+{
+    VSC_SHADER_LIB_LINK_ENTRY         shLibLinkEntry;
+    VSC_SHADER_STAGE_BIT              mainShaderStageBits;
+}VSC_PROG_LIB_LINK_ENTRY;
+
+typedef struct _VSC_SHADER_LIB_LINK_TABLE
+{
+    gctUINT                           shLinkEntryCount;
+    VSC_SHADER_LIB_LINK_ENTRY*        pShLibLinkEntries;
+}VSC_SHADER_LIB_LINK_TABLE;
+
+typedef struct _VSC_PROG_LIB_LINK_TABLE
+{
+    gctUINT                           progLinkEntryCount;
+    VSC_PROG_LIB_LINK_ENTRY*          pProgLibLinkEntries;
+}VSC_PROG_LIB_LINK_TABLE;
+
+END_EXTERN_C();
+
+#endif /*__gc_vsc_drvi_lib_link_h_ */
+
+
diff --git a/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_program_profile.h b/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_program_profile.h
new file mode 100644 (file)
index 0000000..7e1d7b1
--- /dev/null
@@ -0,0 +1,1035 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+/*********************************************************************************
+   Following definitions are ONLY used for openGL(ES)/Vulkan to communicate with
+   client query/binding request from program. NOTE that
+   1. For openGL(ES), ONLY active parts are collected into each high level table.
+      In this case, every table entry has a member pointing to HW resource in SEP.
+   2. For Vulkan, all (whatever it's active or not, whatever the original shaders
+      use or not) must be collected into each high level table as Vulkan's pipeline
+      layout needs all resources in it be allocated into HW resources to avoid driver
+      re-flushing when pipeline is switched. In this case, entry of each table wont
+      point to HW resource in SEP as there might be no such HW resource in SEP which
+      only record info that shader uses.
+**********************************************************************************/
+
+#ifndef __gc_vsc_drvi_program_profile_h_
+#define __gc_vsc_drvi_program_profile_h_
+
+BEGIN_EXTERN_C()
+
+typedef enum _PEP_CLIENT
+{
+    PEP_CLIENT_UNKNOWN                = 0,
+    PEP_CLIENT_GL                     = 1,
+    PEP_CLIENT_VK                     = 2,
+}
+PEP_CLIENT;
+
+typedef enum _GL_DATA_PRECISION
+{
+    GL_DATA_PRECISION_DEFAULT         = 0,
+    GL_DATA_PRECISION_HIGH            = 1,
+    GL_DATA_PRECISION_MEDIUM          = 2,
+    GL_DATA_PRECISION_LOW             = 3,
+}
+GL_DATA_PRECISION;
+
+typedef enum GL_MATRIX_MAJOR
+{
+    GL_MATRIX_MAJOR_ROW               = 0,
+    GL_MATRIX_MAJOR_COLUMN            = 1,
+}
+GL_MATRIX_MAJOR;
+
+typedef enum _GL_FX_BUFFERING_MODE
+{
+    GL_FX_BUFFERING_MODE_INTERLEAVED  = 0,
+    GL_FX_BUFFERING_MODE_SEPARATED    = 1,
+}
+GL_FX_BUFFERING_MODE;
+
+typedef enum GL_FX_STREAMING_MODE
+{
+    GL_FX_STREAMING_MODE_FFU          = 0,
+    GL_FX_STREAMING_MODE_SHADER       = 1,
+}
+GL_FX_STREAMING_MODE;
+
+typedef enum GL_FRAGOUT_USAGE
+{
+    GL_FRAGOUT_USAGE_USER_DEFINED     = 0,
+    GL_FRAGOUT_USAGE_FRAGCOLOR        = 1,
+    GL_FRAGOUT_USAGE_FRAGDATA         = 2,
+}
+GL_FRAGOUT_USAGE;
+
+typedef enum GL_UNIFORM_HW_SUB_MAPPING_MODE
+{
+    GL_UNIFORM_HW_SUB_MAPPING_MODE_CONSTANT     = 0,
+    GL_UNIFORM_HW_SUB_MAPPING_MODE_SAMPLER      = 1,
+}
+GL_UNIFORM_HW_SUB_MAPPING_MODE;
+
+typedef enum GL_UNIFORM_USAGE
+{
+    /* All user defined uniforms will get this type */
+    GL_UNIFORM_USAGE_USER_DEFINED     = 0,
+
+    /* Built-in uniforms */
+    GL_UNIFORM_USAGE_DEPTHRANGE_NEAR  = 1,
+    GL_UNIFORM_USAGE_DEPTHRANGE_FAR   = 2,
+    GL_UNIFORM_USAGE_DEPTHRANGE_DIFF  = 3,
+    GL_UNIFORM_USAGE_HEIGHT           = 4,
+}
+GL_UNIFORM_USAGE;
+
+typedef enum VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING_MODE
+{
+    VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING_MODE_NATIVELY_SUPPORT        = 0,
+    VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING_MODE_NOT_NATIVELY_SUPPORT    = 1,
+}
+VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING_MODE;
+
+
+/**********************************************************************************************************************
+ **********************************     Common program mapping table definitions     **********************************
+ **********************************************************************************************************************/
+
+typedef enum _VSC_RES_ENTRY_BIT
+{
+    VSC_RES_ENTRY_BIT_NONE      = 0x0000,
+    VSC_RES_ENTRY_BIT_8BIT      = 0x0001,
+    VSC_RES_ENTRY_BIT_16BIT     = 0x0002,
+    VSC_RES_ENTRY_BIT_32BIT     = 0x0004,
+}VSC_RES_ENTRY_BIT;
+
+/* Attribute table definition
+
+   For GL(ES),
+       1. glGetActiveAttrib works on boundary of PROG_ATTRIBUTE_TABLE_ENTRY which currently does not support
+          array. It even must work when glLinkProgram failed.
+       2. glGetAttribLocation and other location related functions work on boundary of SHADER_IO_REG_MAPPING,
+          i.e, it must be on vec4 boundary.
+   For Vulkan, no API query, just driver will use to do binding
+*/
+
+typedef struct PROG_ATTRIBUTE_TABLE_ENTRY
+{
+    VSC_SHADER_DATA_TYPE                        type;
+    VSC_RES_ENTRY_BIT                           resEntryBit;
+    gctCONST_STRING                             name;
+    gctUINT                                     nameLength;
+
+    /* Decl'ed array size by GLSL, at this time, it must be 1 */
+    gctSIZE_T                                   arraySize;
+
+    /* Index based on countOfEntries in PROG_ATTRIBUTE_TABLE. It is corresponding to active attribute
+       index */
+    gctUINT                                     attribEntryIndex;
+
+    /* Points to HW IO mapping that VS SEP maintains. Compiler MUST assure ioRegMappings are squeezed
+       together for all active vec4 that activeVec4Mask are masked. So driver just needs go through
+       activeVec4Mask to program partial of type to HW when programing vertexelement/vs input related
+       registers */
+    SHADER_IO_REG_MAPPING*                      pIoRegMapping;
+
+    /* There are 2 types of pre-assigned location, from high priority to low priority
+       1. Shader 'layout(location = ?)' qualifier
+       2. By glBindAttribLocation API call
+
+       If user didn't assign it, we should allocate it then. Each ioRegMapping has a
+       corresponding location. */
+    gctUINT*                                    pLocation;
+    gctUINT                                     locationCount;
+
+    /* How many vec4 'type' can group? For component count of type LT vec4, regarding it as vec4 */
+    gctUINT                                     vec4BasedCount;
+
+    /* To vec4BasedCount vec4 that expanded from type, which are really used by VS */
+    gctUINT                                     activeVec4Mask;
+}
+PROG_ATTRIBUTE_TABLE_ENTRY;
+
+typedef struct PROG_ATTRIBUTE_TABLE
+{
+    /* Entries for active attributes of VS */
+    PROG_ATTRIBUTE_TABLE_ENTRY*                 pAttribEntries;
+    gctUINT                                     countOfEntries;
+
+    /* For query with ACTIVE_ATTRIBUTE_MAX_LENGTH */
+    gctUINT                                     maxLengthOfName;
+}
+PROG_ATTRIBUTE_TABLE;
+
+/* Fragment-output table definition
+
+   For GL(ES),
+       1. No API works on boundary of PROG_FRAGOUT_TABLE_ENTRY.
+       2. glGetFragDataLocation works on boundary of SHADER_IO_REG_MAPPING, i.e, it must be on vec4 boundary.
+   For Vulkan, no API query, just driver will use to do binding
+*/
+
+typedef struct PROG_FRAGOUT_TABLE_ENTRY
+{
+    VSC_SHADER_DATA_TYPE                        type;
+    VSC_RES_ENTRY_BIT                           resEntryBit;
+    gctCONST_STRING                             name;
+    gctUINT                                     nameLength;
+
+    /* Specially for built-in ones */
+    GL_FRAGOUT_USAGE                            usage;
+
+    /* Index based on countOfEntries in PROG_FRAGOUT_TABLE. */
+    gctUINT                                     fragOutEntryIndex;
+
+    /* Points to HW IO mapping that PS SEP maintains. Compiler MUST assure ioRegMappings are squeezed
+       together for all active vec4 that activeVec4Mask are masked. So driver just needs go through
+       activeVec4Mask to program partial of type to HW when programing PE/ps output related registers */
+    SHADER_IO_REG_MAPPING*                      pIoRegMapping;
+
+    /* Shader can have 'layout(location = ?)' qualifier, if so, just use it. Otherwise, we should allocate
+       it then. Each ioRegMapping has a corresponding location. */
+    gctUINT*                                    pLocation;
+    gctUINT                                     locationCount;
+
+    /* How many vec4 'type' can group? For component count of type LT vec4, regarding it as vec4. Since
+       frag output variable can only be scalar or vector, so it actually is the array size GLSL decl'ed */
+    gctUINT                                     vec4BasedCount;
+
+    /* To vec4BasedCount vec4 that expanded from type, which are really used by PS */
+    gctUINT                                     activeVec4Mask;
+}
+PROG_FRAGOUT_TABLE_ENTRY;
+
+typedef struct PROG_FRAGOUT_TABLE
+{
+    /* Entries for active fragment color of fragment shader */
+    PROG_FRAGOUT_TABLE_ENTRY*                   pFragOutEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_FRAGOUT_TABLE;
+
+
+/**********************************************************************************************************************
+ **********************************       GL program mapping table definitions       **********************************
+ **********************************************************************************************************************/
+
+/* Uniform (default uniform-block) table definition
+
+   1. glGetActiveUniform works on boundary of PROG_GL_UNIFORM_TABLE_ENTRY which does not support
+      struct, and the least supported data layout is array. It even must work when glLinkProgram
+      failed.
+   2. glGetUniformLocation and other location related functions work on boundary of element of
+      scalar/vec/matrix/sampler array, i.e, single scalar/vec/matrix/sampler boundary.
+*/
+
+typedef struct PROG_GL_UNIFORM_HW_SUB_MAPPING
+{
+    /* We have 2 choices here
+
+       1. Dynamic-indexed sub array or imm-indexed sub array?
+          For Dynamic-indexed sub array, HW register/memory must be successive, while for imm-indexed
+          sub array, each element can be allocated into anywhere HW can hold it, by which we can reduce
+          HW uniform storage footprint. So do we need split imm-indexed sub array into more pieces??
+
+       2. What's more, do we need much smaller granularity other than element of array, such as vec or
+          channel??
+
+       Currently, imm-indexed sub array is regard as dynamic-indexed sub array and granularity of element
+       of array are used, by which, overhead of driver is small, but HW uniform storage footprint is big.
+    */
+
+    /* Active range of sub array of whole array uniform sized by 'activeArraySize'. */
+    gctUINT                                     startIdx;
+    gctUINT                                     rangeOfSubArray;
+
+    /* Which channels are really used by compiler. For example, vec3 can be 0x07, 0x06 and 0x05,etc and when
+       it is 0x05, although CHANNEL_Y is disabled, compiler will still allocate continuous 3 HW channels for it.
+       That means compiler will assure minimum usage of HW channels while hole is permitted, unless above 2nd
+       choice is channel-based granularity (see commments of validChannelMask of SHADER_CONSTANT_SUB_ARRAY_MAPPING).
+       To driver uniform update, it then can use validChannelMask to match validChannelMask of SHADER_CONSTANT_SUB_ARRAY_MAPPING
+       (further validHWChannelMask) to determine where data goes. For sampler, it must be 0x01 */
+    gctUINT                                     validChannelMask;
+
+    GL_UNIFORM_HW_SUB_MAPPING_MODE              hwSubMappingMode;
+
+    /* Points to HW constant/sampler mapping that SEPs maintains. Compiler assure this active sub range is
+       mapped to successive HW register/memory. */
+    union
+    {
+        /* Directly increase HW regNo or memory address of pSubCBMapping with (4-tuples * (1~4) based on type of
+           element) to access next element of array if 'rangeOfSubArray' is GT 1 */
+        SHADER_CONSTANT_SUB_ARRAY_MAPPING*      pSubCBMapping;
+
+        /* Use (pSamplerMapping ++) to next sampler mapping access if 'rangeOfSubArray' is GT 1 */
+        SHADER_SAMPLER_SLOT_MAPPING*            pSamplerMapping;
+    } hwMapping;
+}
+PROG_GL_UNIFORM_HW_SUB_MAPPING;
+
+typedef struct PROG_GL_UNIFORM_HW_MAPPING
+{
+    /* For following two cases, pHWSubMappings maps whole of uniform to HW resource, and countOfHWSubMappings
+       must be 1.
+
+       a. For GL, when mapping to mem, it looks individual uniform of named uniform block can not be separated
+          into several active sections due to there is no API let user set part of uniform data, so as long as
+          any part of such uniform is used, compiler must deem all data of uniform is used.
+       b. For Vulkan, to support pipeline layout compability, we also must deem all data of uniform is used. */
+    PROG_GL_UNIFORM_HW_SUB_MAPPING*             pHWSubMappings;
+    gctUINT                                     countOfHWSubMappings;
+}
+PROG_GL_UNIFORM_HW_MAPPING;
+
+typedef struct PROG_GL_UNIFORM_COMMON_ENTRY
+{
+    VSC_SHADER_DATA_TYPE                        type;
+    gctCONST_STRING                             name;
+    gctUINT                                     nameLength;
+    GL_DATA_PRECISION                           precision;
+
+    /* Decl'ed array size by GLSL */
+    gctSIZE_T                                   arraySize;
+
+    /* Maximun used element index + 1, considering in whole program scope */
+    gctSIZE_T                                   activeArraySize;
+
+    /* It is corresponding to active uniform index. NOTE that this index is numbered in global
+       scope, including default uniform block and all named uniform blocks */
+    gctUINT                                     uniformEntryIndex;
+
+    /* Different shader stage may have different HW mappings. */
+    PROG_GL_UNIFORM_HW_MAPPING                  hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_GL_UNIFORM_COMMON_ENTRY;
+
+typedef struct PROG_GL_UNIFORM_TABLE_ENTRY
+{
+    PROG_GL_UNIFORM_COMMON_ENTRY                common;
+
+    /* Specially for built-in ones */
+    GL_UNIFORM_USAGE                            usage;
+
+    /* First location index of this uniform, the last location for this uniform is
+       locationBase + (activeArraySize of GL_UNIFORM_COMMON_ENTRY) - 1 */
+    gctUINT                                     locationBase;
+}
+PROG_GL_UNIFORM_TABLE_ENTRY;
+
+typedef struct PROG_GL_UNIFORM_TABLE
+{
+    /* Entries for active uniforms in default uniform block of whole program. They are
+       arranged into 3 chunks in order (sampler + builtin + user-defined) */
+    PROG_GL_UNIFORM_TABLE_ENTRY*                pUniformEntries;
+    gctUINT                                     countOfEntries;
+    gctUINT                                     firstBuiltinUniformEntryIndex;
+    gctUINT                                     firstUserUniformEntryIndex;
+
+    /* For query with ACTIVE_UNIFORM_MAX_LENGTH */
+    gctUINT                                     maxLengthOfName;
+}
+PROG_GL_UNIFORM_TABLE;
+
+/* Uniform-block (named uniform-block, pure constants, can't be samplers) table definition
+
+   1. glGetActiveUniformBlockiv and other uniform block index related functions work on boundary of
+      PROG_GL_UNIFORMBLOCK_TABLE_ENTRY (uniform group).
+   2. glGetActiveUniform works on boundary of PROG_GL_UNIFORMBLOCK_UNIFORM_ENTRY which does not support
+      struct, and the least supported data layout is array. It even must work when glLinkProgram failed.
+   3. Uniforms of uniform-block have no location concept.
+*/
+
+typedef struct PROG_GL_UNIFORMBLOCK_UNIFORM_ENTRY
+{
+    PROG_GL_UNIFORM_COMMON_ENTRY                common;
+
+    /* Layout info for individual uniform of uniform block */
+    gctSIZE_T                                   offset;
+    gctSIZE_T                                   arrayStride;
+    gctSIZE_T                                   matrixStride;
+    GL_MATRIX_MAJOR                             matrixMajor;
+}
+PROG_GL_UNIFORMBLOCK_UNIFORM_ENTRY;
+
+typedef struct PROG_GL_UNIFORMBLOCK_TABLE_ENTRY
+{
+    PROG_GL_UNIFORMBLOCK_UNIFORM_ENTRY*         pUniformEntries;
+    gctUINT                                     countOfEntries;
+
+    /* Each includes copy of uniformEntryIndex of 'common' of pUniformEntries. Whole list is for
+       query with UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */
+    gctUINT*                                    pUniformIndices;
+
+    /* Index based on countOfEntries in PROG_GL_UNIFORMBLOCK_TABLE. It is corresponding to active uniform
+       block index */
+    gctUINT                                     ubEntryIndex;
+
+    /* How many byte size does storage store this uniform block in minimum? */
+    gctUINT                                     dataSizeInByte;
+
+    /* If true, there must be something in hwMappings in PROG_GL_UNIFORM_COMMON_ENTRY */
+    gctBOOL                                     bRefedByShader[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_GL_UNIFORMBLOCK_TABLE_ENTRY;
+
+typedef struct PROG_GL_UNIFORMBLOCK_TABLE
+{
+    /* Entries for active uniform blocks of whole program */
+    PROG_GL_UNIFORMBLOCK_TABLE_ENTRY*           pUniformBlockEntries;
+    gctUINT                                     countOfEntries;
+
+    /* For query with ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */
+    gctUINT                                     maxLengthOfName;
+}
+PROG_GL_UNIFORMBLOCK_TABLE;
+
+/* Transform feedback table definition
+
+   glTransformFeedbackVaryings and glGetTransformFeedbackVarying work on boundary of PROG_GL_XFB_OUT_TABLE_ENTRY.
+*/
+
+typedef struct PROG_GL_XFB_OUT_TABLE_ENTRY
+{
+    VSC_SHADER_DATA_TYPE                        type;
+    gctCONST_STRING                             name;
+    gctUINT                                     nameLength;
+
+    /* Decl'ed array size by GLSL */
+    gctSIZE_T                                   arraySize;
+
+    /* Index based on countOfEntries in PROG_GL_XFB_OUT_TABLE. */
+    gctUINT                                     fxOutEntryIndex;
+
+    /* Data streamming-2-memory mode, by fixed function unit or shader? */
+    GL_FX_STREAMING_MODE                        fxStreamingMode;
+
+    union
+    {
+        /* For writing to XFBO with fixed-function */
+        struct
+        {
+            /* Points to HW IO mapping that VS SEP maintains.
+
+               From spec, if VS has no write to output variable, the value streamed out to buffer is undefined.
+               So, we have 2 choices depending on compiler design.
+
+               1. Compiler MUST assure ioRegMappings are squeezed together for all active vec4 that activeVec4Mask
+                  are masked. So driver needs go through activeVec4Mask to select correct HW reg for active ones and
+                  any of HW reg for unactive ones when programing SO related registers.
+
+               2. Compiler allocate HW regs for vec4 by regarding them all active. In this case, activeVec4Mask still
+                  points out which are really written by VS
+
+               Choice 2 is simple, but choice 1 can get better perf */
+            SHADER_IO_REG_MAPPING*              pIoRegMapping;
+
+            /* How many vec4 'type' can group? For component count of type LT vec4, regarding it as vec4 */
+            gctUINT                             vec4BasedCount;
+
+            /* To vec4BasedCount vec4 that expanded from type, which are really written by VS */
+            gctUINT                             activeVec4Mask;
+        } s;
+
+        /* For the case that shader stores data into XFBO */
+        SHADER_UAV_SLOT_MAPPING*                pSoBufferMapping;
+    } u;
+}
+PROG_GL_XFB_OUT_TABLE_ENTRY;
+
+typedef struct PROG_GL_XFB_OUT_TABLE
+{
+    /* Entries for active transform feedback varyings. pFxOutEntries must be in-orderly corresponding to
+       param 'varyings' of glTransformFeedbackVaryings, and countOfEntries is also corresponding to param
+       'count' of that API */
+    PROG_GL_XFB_OUT_TABLE_ENTRY*                pFxOutEntries;
+    gctUINT                                     countOfEntries;
+
+    /* To control how to serialize to buffer */
+    GL_FX_BUFFERING_MODE                        mode;
+
+    /* For query with TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH */
+    gctUINT                                     maxLengthOfName;
+}
+PROG_GL_XFB_OUT_TABLE;
+
+
+/**********************************************************************************************************************
+ **********************************        VK program mapping table definitions       *********************************
+ **********************************************************************************************************************/
+
+typedef struct PROG_VK_SUB_RESOURCE_BINDING
+{
+    /* Pointer to original API resource binding */
+    VSC_SHADER_RESOURCE_BINDING*                pResBinding;
+
+    /* Start array index in original pResBinding::arraySize */
+    gctUINT                                     startIdxOfSubArray;
+
+    /* Size of sub array size*/
+    gctUINT                                     subArraySize;
+}
+PROG_VK_SUB_RESOURCE_BINDING;
+
+typedef struct PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING
+{
+    /* Index based on countOfArray in PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_POOL. */
+    gctUINT                                     pctsHmEntryIndex;
+
+    /* For sub-array-size m of sampler, and sub-array-size n of tex, if
+       bSamplerMajor is true, the hw sampler will be organized as
+              ((t0, t1, t2...tn), (t0, t1, t2...tn), ...),
+       otherwise it will be organized as
+              ((s0, s1, s2...sm), (s0, s1, s2...sm), ...) */
+    gctBOOL                                     bSamplerMajor;
+
+    /* Texture and sampler part for this private combined tex-sampler */
+    PROG_VK_SUB_RESOURCE_BINDING                texSubBinding;
+    PROG_VK_SUB_RESOURCE_BINDING                samplerSubBinding;
+
+    /* HW sampler slot mapping */
+    SHADER_SAMPLER_SLOT_MAPPING*                pSamplerSlotMapping;
+
+    /* The array size is ((sub-array-size m of sampler) * (sub-array-size n of tex)) */
+    SHADER_PRIV_SAMPLER_ENTRY**                 ppExtraSamplerArray;
+}
+PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING;
+
+typedef struct PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_POOL
+{
+    PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING*      pPrivCombTsHwMappingArray;
+    gctUINT                                     countOfArray;
+}
+PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_POOL, PROG_VK_PRIV_CTS_HW_MAPPING_POOL;
+
+typedef struct PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_LIST
+{
+    /* The entry index (which is indexed to array pPrivCombTsHwMappingArray of
+       PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_POOL) array */
+    gctUINT*                                    pPctsHmEntryIdxArray;
+
+    gctUINT                                     arraySize;
+}PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_LIST;
+
+/* Combined texture sampler table definition
+
+   Must support following resource types
+   VSC_SHADER_RESOURCE_TYPE_COMBINED_IMAGE_SAMPLER
+*/
+
+typedef struct PROG_VK_COMBINED_TEXTURE_SAMPLER_HW_MAPPING
+{
+    /* For the case
+       1. HW natively supports separated sampler, so sampler part of API combined texture
+          sampler will be directly mapped to HW separated sampler
+       2. HW does not natively support separated sampler, so API combined texture sampler
+          is directly mapped to HW combined sampler */
+    SHADER_SAMPLER_SLOT_MAPPING                 samplerMapping;
+
+    /* For the case that HW does not natively support separated sampler. The array size is
+       combTsBinding::arraySize */
+    SHADER_PRIV_SAMPLER_ENTRY**                 ppExtraSamplerArray;
+
+    /* For the case that HW natively supports separated texture, so texture part of API
+       combined texture sampler will be directly mapped to HW separated texture */
+    SHADER_RESOURCE_SLOT_MAPPING                texMapping;
+
+    /* For the case that API combined texture sampler is combined to with other
+       API sampler/texture (HW does not natively support separated sampler) */
+    PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_LIST  samplerHwMappingList;
+    PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_LIST  texHwMappingList;
+}PROG_VK_COMBINED_TEXTURE_SAMPLER_HW_MAPPING;
+
+typedef struct PROG_VK_COMBINED_TEX_SAMPLER_TABLE_ENTRY
+{
+    /* API resource binding */
+    VSC_SHADER_RESOURCE_BINDING                 combTsBinding;
+
+    /* Index based on countOfEntries in PROG_VK_COMBINED_TEXTURE_SAMPLER_TABLE. */
+    gctUINT                                     combTsEntryIndex;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /* For texel buffer, it might need a texture-size attached. As each texel buffer in
+       combTsBinding::arraySize array has texture-size, so this is the first entry
+       of texture-size array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pTextureSize[VSC_MAX_SHADER_STAGE_COUNT][2];
+
+    /* For texel buffer, it might need a lodMinMax attached. As each texel buffer in
+       combTsBinding::arraySize array has lodMinMax, so this is the first entry
+       of lodMinMax array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pLodMinMax[VSC_MAX_SHADER_STAGE_COUNT][2];
+
+    /* For texel buffer, it might need a levelsSamples attached. As each texel buffer in
+       combTsBinding::arraySize array has levelsSamples, so this is the first entry
+       of lodMinMax array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pLevelsSamples[VSC_MAX_SHADER_STAGE_COUNT][2];
+
+    /* Which kinds of inst operation acting on sampler (texture part). The count of
+       this resOpBit is same as combTsBinding::arraySize */
+    VSC_RES_OP_BIT*                             pResOpBits;
+
+    /* Different shader stage may have different HW mappings. */
+    PROG_VK_COMBINED_TEXTURE_SAMPLER_HW_MAPPING hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+
+    /* The sampled image is saved in the storage table, save the index. */
+    gctUINT                                     sampledImageIndexInStorageTable[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_VK_COMBINED_TEX_SAMPLER_TABLE_ENTRY;
+
+typedef struct PROG_VK_COMBINED_TEXTURE_SAMPLER_TABLE
+{
+    PROG_VK_COMBINED_TEX_SAMPLER_TABLE_ENTRY*   pCombTsEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_VK_COMBINED_TEXTURE_SAMPLER_TABLE;
+
+/* Separated-sampler table definition
+
+   Must support following resource types
+   VSC_SHADER_RESOURCE_TYPE_SAMPLER
+*/
+
+typedef union PROG_VK_SEPARATED_SAMPLER_HW_MAPPING
+{
+    /* For HW natively supports separated sampler */
+    SHADER_SAMPLER_SLOT_MAPPING                 samplerMapping;
+
+    /* For HW does not natively supports separated sampler */
+    PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_LIST  samplerHwMappingList;
+}
+PROG_VK_SEPARATED_SAMPLER_HW_MAPPING;
+
+typedef struct PROG_VK_SEPARATED_SAMPLER_TABLE_ENTRY
+{
+    /* API resource binding */
+    VSC_SHADER_RESOURCE_BINDING                 samplerBinding;
+
+    /* Index based on countOfEntries in PROG_VK_SEPARATED_SAMPLER_TABLE. */
+    gctUINT                                     samplerEntryIndex;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /* Which kinds of inst operation acting on sampler. The count of this
+       resOpBit is same as samplerBinding::arraySize */
+    VSC_RES_OP_BIT*                             pResOpBits;
+
+    /* Whether to use hw mapping list in hwMappings. TRUE only under HW
+       does not natively supports separated sampler */
+    gctBOOL                                     bUsingHwMppingList;
+
+    /* Different shader stage may have different HW mappings. */
+    PROG_VK_SEPARATED_SAMPLER_HW_MAPPING        hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_VK_SEPARATED_SAMPLER_TABLE_ENTRY;
+
+typedef struct PROG_VK_SEPARATED_SAMPLER_TABLE
+{
+    PROG_VK_SEPARATED_SAMPLER_TABLE_ENTRY*      pSamplerEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_VK_SEPARATED_SAMPLER_TABLE;
+
+/* Separated-texture table definition
+
+   Must support following resource types if HW supports separated texture
+   VSC_SHADER_RESOURCE_TYPE_SAMPLED_IMAGE
+*/
+
+typedef union PROG_VK_SEPARATED_TEXTURE_HW_MAPPING
+{
+    /* For HW natively supports separated texture */
+    SHADER_RESOURCE_SLOT_MAPPING                    texMapping;
+
+    /* For HW does not natively supports separated texture */
+    struct
+    {
+        /* For a separated image, it might need a image-size attached. As each image in
+           storageBinding::arraySize array has image-size, so this is the first entry
+           of image-size array. */
+        SHADER_PRIV_CONSTANT_ENTRY*                 pImageSize;
+
+        /* Extra layer HW mapping. As currently, for images in in texBinding::arraySize
+           array, if one image has extra image, all other images must have extra image, so
+           this is the first entry of extra-image */
+        SHADER_PRIV_UAV_ENTRY*                      pExtraLayer;
+
+        /* We still need to allocate a constant image for this separated texture for the imageFetch operation.*/
+        SHADER_UAV_SLOT_MAPPING                     hwMapping;
+
+        PROG_VK_PRIV_COMB_TEX_SAMP_HW_MAPPING_LIST  texHwMappingList;
+    } s;
+}
+PROG_VK_SEPARATED_TEXTURE_HW_MAPPING;
+
+typedef struct PROG_VK_SEPARATED_TEXTURE_TABLE_ENTRY
+{
+    /* API resource binding */
+    VSC_SHADER_RESOURCE_BINDING                 texBinding;
+
+    /* Index based on countOfEntries in PROG_VK_SEPARATED_TEXTURE_TABLE. */
+    gctUINT                                     textureEntryIndex;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /* Which kinds of inst operation acting on texture. The count of this
+       resOpBit is same as texBinding::arraySize */
+    VSC_RES_OP_BIT*                             pResOpBits;
+
+    /* Whether to use hw mapping list in hwMappings. TRUE only under HW
+       does not natively supports separated texture */
+    gctBOOL                                     bUsingHwMppingList;
+
+    /* Different shader stage may have different HW mappings. */
+    PROG_VK_SEPARATED_TEXTURE_HW_MAPPING        hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_VK_SEPARATED_TEXTURE_TABLE_ENTRY;
+
+typedef struct PROG_VK_SEPARATED_TEXTURE_TABLE
+{
+    PROG_VK_SEPARATED_TEXTURE_TABLE_ENTRY*      pTextureEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_VK_SEPARATED_TEXTURE_TABLE;
+
+/* Uniform texel buffer table definition
+
+   Must support following resource types
+   VSC_SHADER_RESOURCE_TYPE_UNIFORM_TEXEL_BUFFER
+*/
+
+typedef struct PROG_VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING
+{
+    VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING_MODE     hwMappingMode;
+
+    union
+    {
+        /* For HW natively supports separated texture */
+        SHADER_RESOURCE_SLOT_MAPPING            texMapping;
+
+        /* For HW does not natively supports separated texture */
+        struct
+        {
+            SHADER_HW_MEM_ACCESS_MODE               hwMemAccessMode;
+
+            union
+            {
+                SHADER_SAMPLER_SLOT_MAPPING         samplerMapping;
+
+                SHADER_CONSTANT_HW_LOCATION_MAPPING*pHwDirectAddrBase;
+            } hwLoc;
+
+            /* The array size is utbBinding::arraySize */
+            SHADER_PRIV_SAMPLER_ENTRY**         ppExtraSamplerArray;
+        } s;
+    } u;
+}
+PROG_VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING;
+
+typedef struct PROG_VK_UNIFORM_TEXEL_BUFFER_TABLE_ENTRY
+{
+    /* API resource binding */
+    VSC_SHADER_RESOURCE_BINDING                 utbBinding;
+
+    /* Index based on countOfEntries in PROG_VK_UNIFORM_TEXEL_BUFFER_TABLE. */
+    gctUINT                                     utbEntryIndex;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /*----------------------------------Sampler-related----------------------------------*/
+    /* For texel buffer, it might need a texture-size attached. As each texel buffer in
+       utbBinding::arraySize array has texture-size, so this is the first entry
+       of texture-size array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pTextureSize[VSC_MAX_SHADER_STAGE_COUNT][2];
+
+    /*----------------------------------Image-related----------------------------------*/
+    VSC_IMAGE_FORMAT                            imageFormat;
+
+    /* Which kinds of inst operation acting on texture. The count of this
+       resOpBit is same as utbBinding::arraySize */
+    VSC_RES_OP_BIT*                             pResOpBits;
+
+    /* Different shader stage may have different HW mappings. */
+    PROG_VK_UNIFORM_TEXEL_BUFFER_HW_MAPPING     hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_VK_UNIFORM_TEXEL_BUFFER_TABLE_ENTRY;
+
+typedef struct PROG_VK_UNIFORM_TEXEL_BUFFER_TABLE
+{
+    PROG_VK_UNIFORM_TEXEL_BUFFER_TABLE_ENTRY*    pUtbEntries;
+    gctUINT                                      countOfEntries;
+}
+PROG_VK_UNIFORM_TEXEL_BUFFER_TABLE;
+
+/* Input attachment table definition
+
+   Must support following resource types
+   VSC_SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT
+*/
+
+typedef union PROG_VK_INPUT_ATTACHMENT_HW_MAPPING
+{
+    SHADER_UAV_SLOT_MAPPING                     uavMapping;
+
+    /* For the case that HW does not natively support separated sampler. The array size is
+       iaBinding::arraySize */
+    SHADER_PRIV_SAMPLER_ENTRY**                 ppExtraSamplerArray;
+}
+PROG_VK_INPUT_ATTACHMENT_HW_MAPPING;
+
+typedef struct PROG_VK_INPUT_ATTACHMENT_TABLE_ENTRY
+{
+    /* API resource binding */
+    VSC_SHADER_RESOURCE_BINDING                 iaBinding;
+
+    /* Index based on countOfEntries in PROG_VK_INPUT_ATTACHMENT_TABLE. */
+    gctUINT                                     iaEntryIndex;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /* Different shader stage may have different HW mappings. */
+    PROG_VK_INPUT_ATTACHMENT_HW_MAPPING         hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+
+    /*
+    ** If hwMappings[stageIdx].uavMapping.hwMemAccessMode = SHADER_HW_MEM_ACCESS_MODE_DIRECT_SAMPLER,
+    ** it is treated as a sampler, otherwise it is treated as an image.
+    */
+    /*----------------------------------Image-related----------------------------------*/
+    /* For image storage, it might need a image-size attached. As each image in
+       iaBinding::arraySize array has image-size, so this is the first entry
+       of image-size array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pImageSize[VSC_MAX_SHADER_STAGE_COUNT];
+
+    /* Extra layer HW mapping. As currently, for images in in iaBinding::arraySize
+       array, if one image has extra image, all other images must have extra image, so
+       this is the first entry of extra-image */
+    SHADER_PRIV_UAV_ENTRY*                      pExtraLayer[VSC_MAX_SHADER_STAGE_COUNT];
+
+    /*----------------------------------Sampler-related----------------------------------*/
+    /* For texel buffer, it might need a texture-size attached. As each texel buffer in
+       iaBinding::arraySize array has texture-size, so this is the first entry
+       of texture-size array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pTextureSize[VSC_MAX_SHADER_STAGE_COUNT][2];
+
+    /* For texel buffer, it might need a lodMinMax attached. As each texel buffer in
+       iaBinding::arraySize array has lodMinMax, so this is the first entry
+       of lodMinMax array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pLodMinMax[VSC_MAX_SHADER_STAGE_COUNT][2];
+
+    /* For texel buffer, it might need a levelsSamples attached. As each texel buffer in
+       iaBinding::arraySize array has levelsSamples, so this is the first entry
+       of lodMinMax array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pLevelsSamples[VSC_MAX_SHADER_STAGE_COUNT][2];
+
+    /* Which kinds of inst operation acting on sampler (has flag VIR_SRE_FLAG_TREAT_IA_AS_SAMPLER). The count of
+       this resOpBit is same as iaBinding::arraySize */
+    VSC_RES_OP_BIT*                             pResOpBits;
+}
+PROG_VK_INPUT_ATTACHMENT_TABLE_ENTRY;
+
+typedef struct PROG_VK_INPUT_ATTACHMENT_TABLE
+{
+    PROG_VK_INPUT_ATTACHMENT_TABLE_ENTRY*        pIaEntries;
+    gctUINT                                      countOfEntries;
+}
+PROG_VK_INPUT_ATTACHMENT_TABLE;
+
+/* Storage table definition
+
+   Must support following resource types
+   VSC_SHADER_RESOURCE_TYPE_STORAGE_BUFFER
+   VSC_SHADER_RESOURCE_TYPE_STORAGE_IMAGE
+   VSC_SHADER_RESOURCE_TYPE_STORAGE_TEXEL_BUFFER
+   VSC_SHADER_RESOURCE_TYPE_STORAGE_BUFFER_DYNAMIC
+*/
+
+typedef struct PROG_VK_STORAGE_TABLE_ENTRY
+{
+    /* API resource binding */
+    VSC_SHADER_RESOURCE_BINDING                 storageBinding;
+
+    /* Index based on countOfEntries in PROG_VK_STORAGE_TABLE. */
+    gctUINT                                     storageEntryIndex;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /* For image storage, it might need a image-size attached. As each image in
+       storageBinding::arraySize array has image-size, so this is the first entry
+       of image-size array. */
+    SHADER_PRIV_CONSTANT_ENTRY*                 pImageSize[VSC_MAX_SHADER_STAGE_COUNT];
+
+    /* Extra layer HW mapping. As currently, for images in in storageBinding::arraySize
+       array, if one image has extra image, all other images must have extra image, so
+       this is the first entry of extra-image */
+    SHADER_PRIV_UAV_ENTRY*                      pExtraLayer[VSC_MAX_SHADER_STAGE_COUNT];
+
+    /* Different shader stage may have different HW mappings. */
+    SHADER_UAV_SLOT_MAPPING                     hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_VK_STORAGE_TABLE_ENTRY;
+
+typedef struct PROG_VK_STORAGE_TABLE
+{
+    PROG_VK_STORAGE_TABLE_ENTRY*                pStorageEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_VK_STORAGE_TABLE;
+
+/* Uniform-buffer table definition
+
+   Must support following resource types
+   VSC_SHADER_RESOURCE_TYPE_UNIFORM_BUFFER
+   VSC_SHADER_RESOURCE_TYPE_UNIFORM_BUFFER_DYNAMIC
+*/
+
+typedef struct PROG_VK_UNIFORM_BUFFER_TABLE_ENTRY
+{
+    /* API resource binding */
+    VSC_SHADER_RESOURCE_BINDING                 ubBinding;
+
+    /* Index based on countOfEntries in PROG_VK_UNIFORM_BUFFER_TABLE. */
+    gctUINT                                     ubEntryIndex;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /* Different shader stage may have different HW mappings. */
+    SHADER_CONSTANT_HW_LOCATION_MAPPING         hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_VK_UNIFORM_BUFFER_TABLE_ENTRY;
+
+typedef struct PROG_VK_UNIFORM_BUFFER_TABLE
+{
+    PROG_VK_UNIFORM_BUFFER_TABLE_ENTRY*         pUniformBufferEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_VK_UNIFORM_BUFFER_TABLE;
+
+/* Resource set */
+typedef struct PROG_VK_RESOURCE_SET
+{
+    /* This set only holds the entries with current set-NO in each resource table */
+
+    PROG_VK_COMBINED_TEXTURE_SAMPLER_TABLE      combinedSampTexTable;
+    PROG_VK_SEPARATED_SAMPLER_TABLE             separatedSamplerTable;
+    PROG_VK_SEPARATED_TEXTURE_TABLE             separatedTexTable;
+    PROG_VK_UNIFORM_TEXEL_BUFFER_TABLE          uniformTexBufTable;
+    PROG_VK_INPUT_ATTACHMENT_TABLE              inputAttachmentTable;
+    PROG_VK_STORAGE_TABLE                       storageTable;
+    PROG_VK_UNIFORM_BUFFER_TABLE                uniformBufferTable;
+}
+PROG_VK_RESOURCE_SET;
+
+/* Push-constant table definition */
+
+typedef struct PROG_VK_PUSH_CONSTANT_TABLE_ENTRY
+{
+    /* API push-constant range */
+    VSC_SHADER_PUSH_CONSTANT_RANGE              pushConstRange;
+
+    /* Which shader stages access this entry */
+    VSC_SHADER_STAGE_BIT                        stageBits;
+
+    /* Is this entry really used by shader */
+    gctUINT                                     activeStageMask;
+
+    /* Different shader stage may have different HW mappings. */
+    SHADER_CONSTANT_HW_LOCATION_MAPPING         hwMappings[VSC_MAX_SHADER_STAGE_COUNT];
+}
+PROG_VK_PUSH_CONSTANT_TABLE_ENTRY;
+
+typedef struct PROG_VK_PUSH_CONSTANT_TABLE
+{
+    PROG_VK_PUSH_CONSTANT_TABLE_ENTRY*          pPushConstantEntries;
+    gctUINT                                     countOfEntries;
+}
+PROG_VK_PUSH_CONSTANT_TABLE;
+
+/* Executable program profile definition. It is generated only when glLinkProgram or glProgramBinary
+   calling. Each client program only has one profile like this. */
+typedef struct PROGRAM_EXECUTABLE_PROFILE
+{
+    PEP_CLIENT                                  pepClient;
+
+    /* The executable shaders that this program contains. */
+    SHADER_EXECUTABLE_PROFILE                   seps[VSC_MAX_SHADER_STAGE_COUNT];
+
+    /* I/O high level mapping tables (high level variable to #, pointing to entry of SEP) */
+    PROG_ATTRIBUTE_TABLE                        attribTable;
+    PROG_FRAGOUT_TABLE                          fragOutTable;
+
+    /* Other high level mapping tables */
+    union
+    {
+        /* GL client only. High level variable to #, pointing to entry of SEP */
+        struct
+        {
+            PROG_GL_UNIFORM_TABLE               uniformTable;
+            PROG_GL_UNIFORMBLOCK_TABLE          uniformBlockTable;
+            PROG_GL_XFB_OUT_TABLE               fxOutTable;
+        } gl;
+
+        /* Vulkan client only. High level binding to hw resource */
+        struct
+        {
+            PROG_VK_RESOURCE_SET*               pResourceSets;
+            gctUINT32                           resourceSetCount;
+
+            PROG_VK_PUSH_CONSTANT_TABLE         pushConstantTable;
+
+            /* It is not part of API resources, but for some HWs which does not support separated
+               texture/sampler, api texture/sampler need to be combined by ourselves, so we need
+               a separated private combined texture sampler table to maintain all pairs of api
+               texture/sampler which have a specific hw mapping */
+            PROG_VK_PRIV_CTS_HW_MAPPING_POOL    privateCombTsHwMappingPool;
+        } vk;
+    } u;
+}
+PROGRAM_EXECUTABLE_PROFILE;
+
+gceSTATUS vscInitializePEP(PROGRAM_EXECUTABLE_PROFILE* pPEP);
+gceSTATUS vscFinalizePEP(PROGRAM_EXECUTABLE_PROFILE* pPEP);
+
+END_EXTERN_C();
+
+#endif /* __gc_vsc_drvi_program_profile_h_ */
+
+
diff --git a/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_shader_priv_mapping.h b/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_shader_priv_mapping.h
new file mode 100644 (file)
index 0000000..77de12b
--- /dev/null
@@ -0,0 +1,265 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_vsc_drvi_shader_priv_mapping_h_
+#define __gc_vsc_drvi_shader_priv_mapping_h_
+
+BEGIN_EXTERN_C()
+
+/* Forward declarations */
+typedef struct _SHADER_CONSTANT_SUB_ARRAY_MAPPING SHADER_CONSTANT_SUB_ARRAY_MAPPING;
+typedef struct _SHADER_COMPILE_TIME_CONSTANT      SHADER_COMPILE_TIME_CONSTANT;
+typedef struct _SHADER_UAV_SLOT_MAPPING           SHADER_UAV_SLOT_MAPPING;
+typedef struct _SHADER_RESOURCE_SLOT_MAPPING      SHADER_RESOURCE_SLOT_MAPPING;
+typedef struct _SHADER_SAMPLER_SLOT_MAPPING       SHADER_SAMPLER_SLOT_MAPPING;
+typedef struct _SHADER_IO_REG_MAPPING             SHADER_IO_REG_MAPPING;
+
+/* Shader constant static priv-mapping kind */
+typedef enum SHS_PRIV_CONSTANT_KIND
+{
+    SHS_PRIV_CONSTANT_KIND_COMPUTE_GROUP_NUM                = 0,
+    SHS_PRIV_CONSTANT_KIND_IMAGE_SIZE                       = 1,
+    SHS_PRIV_CONSTANT_KIND_TEXTURE_SIZE                     = 2,
+    SHS_PRIV_CONSTANT_KIND_LOD_MIN_MAX                      = 3,
+    SHS_PRIV_CONSTANT_KIND_LEVELS_SAMPLES                   = 4,
+    SHS_PRIV_CONSTANT_KIND_BASE_INSTANCE                    = 5,
+    SHS_PRIV_CONSTANT_KIND_SAMPLE_LOCATION                  = 6,
+    SHS_PRIV_CONSTANT_KIND_ENABLE_MULTISAMPLE_BUFFERS       = 7,
+    SHS_PRIV_CONSTANT_KIND_LOCAL_ADDRESS_SPACE              = 8,
+    SHS_PRIV_CONSTANT_KIND_PRIVATE_ADDRESS_SPACE            = 9,
+    SHS_PRIV_CONSTANT_KIND_CONSTANT_ADDRESS_SPACE           = 10,
+    SHS_PRIV_CONSTANT_KIND_GLOBAL_SIZE                      = 11,
+    SHS_PRIV_CONSTANT_KIND_LOCAL_SIZE                       = 12,
+    SHS_PRIV_CONSTANT_KIND_GLOBAL_OFFSET                    = 13,
+    SHS_PRIV_CONSTANT_KIND_WORK_DIM                         = 14,
+    SHS_PRIV_CONSTANT_KIND_PRINTF_ADDRESS                   = 15,
+    SHS_PRIV_CONSTANT_KIND_WORKITEM_PRINTF_BUFFER_SIZE      = 16,
+    SHS_PRIV_CONSTANT_KIND_WORK_THREAD_COUNT                = 17,
+    SHS_PRIV_CONSTANT_KIND_WORK_GROUP_COUNT                 = 18,
+    SHS_PRIV_CONSTANT_KIND_LOCAL_MEM_SIZE                   = 19,
+    SHS_PRIV_CONSTANT_KIND_WORK_GROUP_ID_OFFSET             = 20,
+    SHS_PRIV_CONSTANT_KIND_GLOBAL_INVOCATION_ID_OFFSET      = 21,
+    SHS_PRIV_CONSTANT_KIND_TEMP_REG_SPILL_MEM_ADDRESS       = 22,
+    SHS_PRIV_CONSTANT_KIND_GLOBAL_WORK_SCALE                = 23,
+    SHS_PRIV_CONSTANT_KIND_DATA_BIT_SIZE                    = 24,
+    SHS_PRIV_CONSTANT_KIND_COMPUTE_GROUP_NUM_FOR_SINGLE_GPU = 25,
+    SHS_PRIV_CONSTANT_KIND_VIEW_INDEX                       = 26,
+    SHS_PRIV_CONSTANT_KIND_DEFAULT_UBO_ADDRESS              = 27,
+    SHS_PRIV_CONSTANT_KIND_COUNT, /* last member, add new kind beofre this */
+}SHS_PRIV_CONSTANT_KIND;
+
+/* Shader mem static priv-mapping kind */
+typedef enum SHS_PRIV_MEM_KIND
+{
+    SHS_PRIV_MEM_KIND_GPR_SPILLED_MEMORY        = 0, /* For gpr register spillage */
+    SHS_PRIV_MEM_KIND_CONSTANT_SPILLED_MEMORY   = 1, /* For constant register spillage */
+    SHS_PRIV_MEM_KIND_STREAMOUT_BY_STORE        = 2, /* Stream buffer for SO */
+    SHS_PRIV_MEM_KIND_CL_PRIVATE_MEMORY         = 3, /* For CL private mem */
+    SHS_PRIV_MEM_KIND_SHARED_MEMORY             = 4, /* For CL local memory or DirectCompute shared mem */
+    SHS_PRIV_MEM_KIND_EXTRA_UAV_LAYER           = 5,
+    SHS_PRIV_MEM_KIND_COUNT                     = 6,
+}SHS_PRIV_MEM_KIND;
+
+/* !!!!!NOTE: For dynamic (lib-link) patch, the priv-mapping flag will directly use VSC_LIB_LINK_TYPE!!!!! */
+
+/* Definition for common entry of shader priv mapping . */
+typedef struct SHADER_PRIV_MAPPING_COMMON_ENTRY
+{
+    /* Each priv-mapping kind */
+    gctUINT                                     privmKind;
+
+    /* For some kinds, there might be multiple mapping, so flag-index to distinguish them.
+       It is numbered from zero. */
+    gctUINT                                     privmKindIndex;
+
+    /* For some flags, they will have their private data to tell driver how to do. */
+    gctBOOL                                     notAllocated;
+    void*                                       pPrivateData;
+}
+SHADER_PRIV_MAPPING_COMMON_ENTRY;
+
+/*
+  Definition of shader constants priv-mapping
+*/
+
+typedef enum SHADER_PRIV_CONSTANT_MODE
+{
+    SHADER_PRIV_CONSTANT_MODE_CTC           = 0,
+    SHADER_PRIV_CONSTANT_MODE_VAL_2_INST    = 1,
+    SHADER_PRIV_CONSTANT_MODE_VAL_2_MEMORREG= 2,
+    SHADER_PRIV_CONSTANT_MODE_VAL_2_DUBO    = 3,
+}
+SHADER_PRIV_CONSTANT_MODE;
+
+typedef struct SHADER_PRIV_CONSTANT_INST_IMM
+{
+    gctUINT                                     patchedPC;
+    gctUINT                                     srcNo;
+}
+SHADER_PRIV_CONSTANT_INST_IMM;
+
+typedef struct SHADER_PRIV_CONSTANT_CTC
+{
+    SHADER_COMPILE_TIME_CONSTANT*               pCTC;
+    gctUINT                                     hwChannelMask;
+}
+SHADER_PRIV_CONSTANT_CTC;
+
+typedef struct SHADER_PRIV_CONSTANT_ENTRY
+{
+    SHADER_PRIV_MAPPING_COMMON_ENTRY            commonPrivm;
+
+    /* Which mode that driver use to flush constant */
+    SHADER_PRIV_CONSTANT_MODE                   mode;
+
+    union
+    {
+        SHADER_CONSTANT_SUB_ARRAY_MAPPING*      pSubCBMapping; /* SHADER_PRIV_CONSTANT_MODE_VAL_2_MEMORREG */
+        SHADER_PRIV_CONSTANT_CTC                ctcConstant;   /* SHADER_PRIV_CONSTANT_MODE_CTC */
+        SHADER_PRIV_CONSTANT_INST_IMM           instImm;       /* SHADER_PRIV_CONSTANT_MODE_VAL_2_INST */
+        gctUINT                                 duboEntryIndex;/* SHADER_PRIV_CONSTANT_MODE_VAL_2_DUBO */
+    } u;
+}
+SHADER_PRIV_CONSTANT_ENTRY;
+
+typedef struct SHADER_PRIV_CONSTANT_MAPPING
+{
+    SHADER_PRIV_CONSTANT_ENTRY*                 pPrivmConstantEntries;
+    gctUINT                                     countOfEntries;
+}
+SHADER_PRIV_CONSTANT_MAPPING;
+
+/*
+  Definition of shader uav priv-mapping
+*/
+
+typedef struct SHADER_PRIV_MEM_DATA_MAPPING
+{
+    SHADER_COMPILE_TIME_CONSTANT**              ppCTC;
+    gctUINT                                     ctcCount;
+
+    SHADER_CONSTANT_SUB_ARRAY_MAPPING**         ppCnstSubArray;
+    gctUINT                                     cnstSubArrayCount;
+}SHADER_PRIV_MEM_DATA_MAPPING;
+
+typedef struct SHADER_PRIV_UAV_ENTRY
+{
+    SHADER_PRIV_MAPPING_COMMON_ENTRY            commonPrivm;
+
+    /* The data which will be set to this memory */
+    SHADER_PRIV_MEM_DATA_MAPPING                memData;
+
+    SHADER_UAV_SLOT_MAPPING*                    pBuffer;
+}
+SHADER_PRIV_UAV_ENTRY;
+
+typedef struct SHADER_PRIV_UAV_MAPPING
+{
+    SHADER_PRIV_UAV_ENTRY*                      pPrivUavEntries;
+    gctUINT                                     countOfEntries;
+}
+SHADER_PRIV_UAV_MAPPING;
+
+/*
+  Definition of shader resource priv-mapping
+*/
+
+typedef struct SHADER_PRIV_RESOURCE_ENTRY
+{
+    SHADER_PRIV_MAPPING_COMMON_ENTRY            commonPrivm;
+    SHADER_RESOURCE_SLOT_MAPPING*               pSrv;
+}
+SHADER_PRIV_RESOURCE_ENTRY;
+
+typedef struct SHADER_PRIV_RESOURCE_MAPPING
+{
+    SHADER_PRIV_RESOURCE_ENTRY*                 pPrivResourceEntries;
+    gctUINT                                     countOfEntries;
+}
+SHADER_PRIV_RESOURCE_MAPPING;
+
+/*
+  Definition of shader sampler priv-mapping
+*/
+
+typedef struct SHADER_PRIV_SAMPLER_ENTRY
+{
+    SHADER_PRIV_MAPPING_COMMON_ENTRY            commonPrivm;
+    SHADER_SAMPLER_SLOT_MAPPING*                pSampler;
+}
+SHADER_PRIV_SAMPLER_ENTRY;
+
+typedef struct SHADER_PRIV_SAMPLER_MAPPING
+{
+    SHADER_PRIV_SAMPLER_ENTRY*                  pPrivSamplerEntries;
+    gctUINT                                     countOfEntries;
+}
+SHADER_PRIV_SAMPLER_MAPPING;
+
+/*
+  Definition of shader output priv-mapping
+*/
+
+typedef struct SHADER_PRIV_OUTPUT_ENTRY
+{
+    SHADER_PRIV_MAPPING_COMMON_ENTRY            commonPrivm;
+    SHADER_IO_REG_MAPPING*                      pOutput;
+}
+SHADER_PRIV_OUTPUT_ENTRY;
+
+typedef struct SHADER_PRIV_OUTPUT_MAPPING
+{
+    SHADER_PRIV_OUTPUT_ENTRY*                   pPrivOutputEntries;
+    gctUINT                                     countOfEntries;
+}
+SHADER_PRIV_OUTPUT_MAPPING;
+
+/* Static private mapping table */
+typedef struct SHADER_STATIC_PRIV_MAPPING
+{
+     SHADER_PRIV_CONSTANT_MAPPING               privConstantMapping;
+     SHADER_PRIV_UAV_MAPPING                    privUavMapping;
+}SHADER_STATIC_PRIV_MAPPING;
+
+/* Dynamic private mapping table */
+typedef struct SHADER_DYNAMIC_PRIV_MAPPING
+{
+     SHADER_PRIV_SAMPLER_MAPPING                privSamplerMapping;
+     SHADER_PRIV_OUTPUT_MAPPING                 privOutputMapping;
+}SHADER_DYNAMIC_PRIV_MAPPING;
+
+/* Default UBO mapping. */
+typedef enum SHS_DEFAULT_UBO_MEMBER_KIND
+{
+    SHS_DEFAULT_UBO_MEMBER_PRIV_CONST           = 0,
+}SHS_DEFAULT_UBO_MEMBER_KIND;
+
+typedef struct SHADER_DEFAULT_UBO_MEMBER_ENTRY
+{
+    gctUINT                                     memberIndexInOtherEntryTable;
+    SHS_DEFAULT_UBO_MEMBER_KIND                 memberKind;
+    gctUINT                                     offsetInByte;
+}SHADER_DEFAULT_UBO_MEMBER_ENTRY;
+
+typedef struct SHADER_DEFAULT_UBO_MAPPING
+{
+    gctUINT                                     baseAddressIndexInPrivConstTable;
+    SHADER_DEFAULT_UBO_MEMBER_ENTRY*            pDefaultUboMemberEntries;
+    gctUINT                                     countOfEntries;
+    gctUINT                                     sizeInByte;
+}SHADER_DEFAULT_UBO_MAPPING;
+
+END_EXTERN_C();
+
+#endif /* __gc_vsc_drvi_shader_priv_mapping_h_ */
+
diff --git a/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_shader_profile.h b/drivers/amlogic/npu/inc/drvi/gc_vsc_drvi_shader_profile.h
new file mode 100644 (file)
index 0000000..2b40dc9
--- /dev/null
@@ -0,0 +1,1533 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+/***********************************************************************************
+   All following definitions are designed for DX/openGL(ES)/Vulkan/openCL drivers to
+   manage to do shaders' HW-level linkage programming, shader flush programming and
+   shader level recompiler. NOTE that only info that shader uses (these info must be
+   assigned specific HW resource for them) are recorded in SEP, any other redundant
+   info will not be recorded in SEP.
+************************************************************************************/
+#ifndef __gc_vsc_drvi_shader_profile_h_
+#define __gc_vsc_drvi_shader_profile_h_
+
+BEGIN_EXTERN_C()
+
+/* In-order needs compiler allocate inputs based on io-index ordering, will enable after
+   fully switching to new code-gen */
+#define IO_HW_LOC_NUMBER_IN_ORDER                0
+
+/* Whether hwRegChannel of SHADER_IO_CHANNEL_MAPPING is identical to channel designating to
+   this SHADER_IO_CHANNEL_MAPPING. When it is disabled, any hwRegChannel can be allocated to
+   this SHADER_IO_CHANNEL_MAPPING */
+#define IO_HW_CHANNEL_IDENTICAL_TO_IO_LL_CHANNEL 1
+
+/* Some macroes for SEP profile version */
+#define ENCODE_SEP_VER_TYPE(major, minor)      ((((major)  & 0xFF) << 0x08) | \
+                                                (((minor)  & 0xFF) << 0x00))
+
+#define DECODE_SEP_MAJOR_VER(vt)      (((vt) >> 0x08) & 0xFF)
+#define DECODE_SEP_MINOR_VER(vt)      (((vt) >> 0x00) & 0xFF)
+
+/* Some macroes for version type */
+#define ENCODE_SHADER_VER_TYPE(client, type, major, minor)      ((((client) & 0xFF) << 0x18) | \
+                                                                 (((type)   & 0xFF) << 0x10) | \
+                                                                 (((major)  & 0xFF) << 0x08) | \
+                                                                 (((minor)  & 0xFF) << 0x00))
+#define DECODE_SHADER_CLIENT(vt)         (((vt) >> 0x18) & 0xFF)
+#define DECODE_SHADER_TYPE(vt)           (((vt) >> 0x10) & 0xFF)
+#define DECODE_SHADER_MAJOR_VER(vt)      (((vt) >> 0x08) & 0xFF)
+#define DECODE_SHADER_MINOR_VER(vt)      (((vt) >> 0x00) & 0xFF)
+
+/* Capability definition of executable profile */
+
+#define MAX_SHADER_IO_NUM                      36
+
+/* 0~15 for client normal constant buffers, such as DX cb/icb or GLES uniform block
+   16 for normal uniforms of OGL(ES), AKA, default uniform block
+   17 for LTC constants
+   18 for immediate values
+   19~31 for other internal usages of constant buffers for patches and other recompiler requests */
+#define MAX_SHADER_CONSTANT_ARRAY_NUM          32
+#define GLCL_NORMAL_UNIFORM_CONSTANT_ARRAY     16
+#define LTC_CONSTANT_ARRAY                     GLCL_NORMAL_UNIFORM_CONSTANT_ARRAY + 1
+#define IMM_CONSTANT_ARRAY                     LTC_CONSTANT_ARRAY + 1
+#define START_CONSTANT_ARRAY_FOR_PATCH         IMM_CONSTANT_ARRAY + 1
+
+#define MAX_SHADER_SAMPLER_NUM                 16
+#define MAX_SHADER_RESOURCE_NUM                128
+#define MAX_SHADER_STREAM_OUT_BUFFER_NUM       4
+#define MAX_SHADER_UAV_NUM                     8
+
+/* Channel definition */
+
+#define CHANNEL_NUM                            4
+#define CHANNEL_X                              0  /* R */
+#define CHANNEL_Y                              1  /* G */
+#define CHANNEL_Z                              2  /* B */
+#define CHANNEL_W                              3  /* A */
+
+#define WRITEMASK_X                            0x1
+#define WRITEMASK_Y                            0x2
+#define WRITEMASK_Z                            0x4
+#define WRITEMASK_W                            0x8
+#define WRITEMASK_XY                           (WRITEMASK_X|WRITEMASK_Y)
+#define WRITEMASK_XYZ                          (WRITEMASK_X|WRITEMASK_Y|WRITEMASK_Z)
+#define WRITEMASK_XYZW                         (WRITEMASK_X|WRITEMASK_Y|WRITEMASK_Z|WRITEMASK_W)
+#define WRITEMASK_ALL                          WRITEMASK_XYZW
+#define WRITEMASK_NONE                         0x0
+
+#define NOT_ASSIGNED                           0xFFFFFFFF
+
+typedef enum SHADER_TYPE
+{
+    SHADER_TYPE_UNKNOWN             = 0,
+    SHADER_TYPE_VERTEX              = 1,
+    SHADER_TYPE_PIXEL               = 2,
+    SHADER_TYPE_GEOMETRY            = 3,
+    SHADER_TYPE_HULL                = 4, /* TCS/TI */
+    SHADER_TYPE_DOMAIN              = 5, /* TES/TS */
+
+    /* GPGPU shader, such as openCL and DX's compute */
+    SHADER_TYPE_GENERAL             = 6,
+
+    /* It is not a shader, but indicates a fixed-function unit. */
+    SHADER_TYPE_FFU                 = SHADER_TYPE_UNKNOWN,
+}
+SHADER_TYPE;
+
+typedef enum SHADER_CLIENT
+{
+    SHADER_CLIENT_UNKNOWN           = 0,
+    SHADER_CLIENT_DX                = 1,
+    SHADER_CLIENT_GL                = 2,
+    SHADER_CLIENT_GLES              = 3,
+    SHADER_CLIENT_CL                = 4,
+    SHADER_CLIENT_VK                = 5,
+}
+SHADER_CLIENT;
+
+typedef enum SHADER_IO_USAGE
+{
+    /* 0 - 13 must be equal to D3DDECLUSAGE!!!!!!! SO DONT CHANGE THEIR VALUES!!!! */
+
+    /* Common usages, for gfx clients only */
+    SHADER_IO_USAGE_POSITION                 = 0,
+    SHADER_IO_USAGE_TESSFACTOR               = 8,
+    SHADER_IO_USAGE_ISFRONTFACE              = 18,
+
+    /* For gfx clients only, but excluding DX1x */
+    SHADER_IO_USAGE_BLENDWEIGHT              = 1,
+    SHADER_IO_USAGE_BLENDINDICES             = 2,
+    SHADER_IO_USAGE_NORMAL                   = 3,
+    SHADER_IO_USAGE_POINTSIZE                = 4,
+    SHADER_IO_USAGE_TEXCOORD                 = 5,
+    SHADER_IO_USAGE_TANGENT                  = 6,
+    SHADER_IO_USAGE_BINORMAL                 = 7,
+    SHADER_IO_USAGE_TRANSFORMEDPOS           = 9,
+    SHADER_IO_USAGE_COLOR                    = 10,
+    SHADER_IO_USAGE_FOG                      = 11,
+    SHADER_IO_USAGE_DEPTH                    = 12,
+    SHADER_IO_USAGE_SAMPLE                   = 13,
+
+    /* For gfx clients only, but excluding DX9 - SGV */
+    SHADER_IO_USAGE_VERTEXID                 = 14,
+    SHADER_IO_USAGE_PRIMITIVEID              = 15,
+    SHADER_IO_USAGE_INSTANCEID               = 16,
+    SHADER_IO_USAGE_INPUTCOVERAGE            = 17,
+    SHADER_IO_USAGE_SAMPLE_INDEX             = 19,
+    SHADER_IO_USAGE_OUTPUTCONTROLPOINTID     = 20,
+    SHADER_IO_USAGE_FORKINSTANCEID           = 21,
+    SHADER_IO_USAGE_JOININSTANCEID           = 22,
+    SHADER_IO_USAGE_DOMAIN_LOCATION          = 23,
+
+    /* For GPGPU client only */
+    SHADER_IO_USAGE_THREADID                 = 24,
+    SHADER_IO_USAGE_THREADGROUPID            = 25,
+    SHADER_IO_USAGE_THREADIDINGROUP          = 26,
+    SHADER_IO_USAGE_THREADIDINGROUPFLATTENED = 27,
+
+    /* For gfx clients only, but excluding DX9 - SIV */
+    SHADER_IO_USAGE_CLIPDISTANCE             = 28,
+    SHADER_IO_USAGE_CULLDISTANCE             = 29,
+    SHADER_IO_USAGE_RENDERTARGETARRAYINDEX   = 30,
+    SHADER_IO_USAGE_VIEWPORTARRAYINDEX       = 31,
+    SHADER_IO_USAGE_DEPTHGREATEREQUAL        = 32,
+    SHADER_IO_USAGE_DEPTHLESSEQUAL           = 33,
+    SHADER_IO_USAGE_INSIDETESSFACTOR         = 34,
+    SHADER_IO_USAGE_SAMPLE_MASK              = 35,
+
+    /* For gfx clients only, and only for GL */
+    SHADER_IO_USAGE_POINT_COORD              = 36,
+    SHADER_IO_USAGE_FOG_COORD                = 37,
+    SHADER_IO_USAGE_HELPER_PIXEL             = 38,
+
+    /* For gfx pixel-frequency only (sample-frequency will directly use SHADER_IO_USAGE_DEPTH),
+       HW internal SGV/SIV, no client spec refer to it. */
+    SHADER_IO_USAGE_SAMPLE_DEPTH             = 39,
+
+    /* For gfx sample-frequency only */
+    SHADER_IO_USAGE_SAMPLE_POSITION          = 40,
+
+    /* For gfx's HS/DS/GS only, and only for GL */
+    SHADER_IO_USAGE_INPUT_VTX_CP_COUNT       = 41,
+
+    /* For gfx's GS only */
+    SHADER_IO_USAGE_INSTANCING_ID            = 42,
+
+    /* A special usage which means IO is used by general purpose */
+    SHADER_IO_USAGE_GENERAL                  = 43,
+
+    /* Add NEW usages here */
+
+    /* Must be at last!!!!!!! */
+    SHADER_IO_USAGE_TOTAL_COUNT,
+}
+SHADER_IO_USAGE;
+
+#define IS_SHADER_IO_USAGE_SGV(usage)                                                                \
+    (((usage) >= SHADER_IO_USAGE_VERTEXID && (usage) <= SHADER_IO_USAGE_THREADIDINGROUPFLATTENED) || \
+     ((usage) == SHADER_IO_USAGE_ISFRONTFACE)                                                     || \
+     ((usage) == SHADER_IO_USAGE_SAMPLE_MASK)                                                     || \
+     ((usage) == SHADER_IO_USAGE_SAMPLE_POSITION)                                                 || \
+     ((usage) >= SHADER_IO_USAGE_POINT_COORD && (usage) <= SHADER_IO_USAGE_INSTANCING_ID))
+
+#define IS_SHADER_IO_USAGE_SIV(usage)                                                                \
+    (((usage) >= SHADER_IO_USAGE_CLIPDISTANCE && (usage) <= SHADER_IO_USAGE_SAMPLE_MASK)          || \
+     ((usage) == SHADER_IO_USAGE_POSITION)                                                        || \
+     ((usage) == SHADER_IO_USAGE_TESSFACTOR)                                                      || \
+     ((usage) == SHADER_IO_USAGE_SAMPLE_DEPTH)                                                    || \
+     ((usage) == SHADER_IO_USAGE_POINTSIZE))
+
+#define IS_SHADER_IO_USAGE_SV(usage) (IS_SHADER_IO_USAGE_SGV((usage)) && IS_SHADER_IO_USAGE_SIV((usage)))
+
+typedef enum SHADER_CONSTANT_USAGE
+{
+    /* DX9 only */
+    SHADER_CONSTANT_USAGE_FLOAT              = 0,
+    SHADER_CONSTANT_USAGE_INTEGER            = 1,
+    SHADER_CONSTANT_USAGE_BOOLEAN            = 2,
+
+    /* For other clients */
+    SHADER_CONSTANT_USAGE_MIXED              = 3,
+
+    /* Must be at last!!!!!!! */
+    SHADER_CONSTANT_USAGE_TOTAL_COUNT        = 4,
+}
+SHADER_CONSTANT_USAGE;
+
+typedef enum SHADER_RESOURCE_DIMENSION
+{
+    SHADER_RESOURCE_DIMENSION_UNKNOW         = 0,
+    SHADER_RESOURCE_DIMENSION_BUFFER         = 1,
+    SHADER_RESOURCE_DIMENSION_1D             = 2,
+    SHADER_RESOURCE_DIMENSION_1DARRAY        = 3,
+    SHADER_RESOURCE_DIMENSION_2D             = 4,
+    SHADER_RESOURCE_DIMENSION_2DARRAY        = 5,
+    SHADER_RESOURCE_DIMENSION_2DMS           = 6,
+    SHADER_RESOURCE_DIMENSION_2DMSARRAY      = 7,
+    SHADER_RESOURCE_DIMENSION_3D             = 8,
+    SHADER_RESOURCE_DIMENSION_CUBE           = 9,
+    SHADER_RESOURCE_DIMENSION_CUBEARRAY      = 10,
+
+    /* Must be at last!!!!!!! */
+    SHADER_RESOURCE_DIMENSION_TOTAL_COUNT,
+}
+SHADER_RESOURCE_DIMENSION;
+
+typedef enum SHADER_SAMPLER_MODE
+{
+    SHADER_SAMPLER_MODE_DEFAULT              = 0,
+    SHADER_SAMPLER_MODE_COMPARISON           = 1,
+    SHADER_SAMPLER_MODE_MONO                 = 2,
+}
+SHADER_SAMPLER_MODE;
+
+typedef enum SHADER_RESOURCE_RETURN_TYPE
+{
+    SHADER_RESOURCE_RETURN_TYPE_UNORM        = 0,
+    SHADER_RESOURCE_RETURN_TYPE_SNORM        = 1,
+    SHADER_RESOURCE_RETURN_TYPE_SINT         = 2,
+    SHADER_RESOURCE_RETURN_TYPE_UINT         = 3,
+    SHADER_RESOURCE_RETURN_TYPE_FLOAT        = 4,
+}
+SHADER_RESOURCE_RETURN_TYPE;
+
+typedef enum SHADER_RESOURCE_ACCESS_MODE
+{
+    SHADER_RESOURCE_ACCESS_MODE_TYPE         = 0,
+    SHADER_RESOURCE_ACCESS_MODE_RAW          = 1,
+    SHADER_RESOURCE_ACCESS_MODE_STRUCTURED   = 2,
+}
+SHADER_RESOURCE_ACCESS_MODE;
+
+typedef enum SHADER_UAV_DIMENSION
+{
+    SHADER_UAV_DIMENSION_UNKNOWN             = 0,
+    SHADER_UAV_DIMENSION_BUFFER              = 1,
+    SHADER_UAV_DIMENSION_1D                  = 2,
+    SHADER_UAV_DIMENSION_1DARRAY             = 3,
+    SHADER_UAV_DIMENSION_2D                  = 4,
+    SHADER_UAV_DIMENSION_2DARRAY             = 5,
+    SHADER_UAV_DIMENSION_3D                  = 6,
+
+    /* Must be at last!!!!!!! */
+    SHADER_UAV_DIMENSION_TOTAL_COUNT,
+}
+SHADER_UAV_DIMENSION;
+
+typedef enum SHADER_UAV_TYPE
+{
+    SHADER_UAV_TYPE_UNORM                    = 0,
+    SHADER_UAV_TYPE_SNORM                    = 1,
+    SHADER_UAV_TYPE_SINT                     = 2,
+    SHADER_UAV_TYPE_UINT                     = 3,
+    SHADER_UAV_TYPE_FLOAT                    = 4,
+}
+SHADER_UAV_TYPE;
+
+typedef enum SHADER_UAV_ACCESS_MODE
+{
+    SHADER_UAV_ACCESS_MODE_TYPE              = 0,
+    SHADER_UAV_ACCESS_MODE_RAW               = 1,
+    SHADER_UAV_ACCESS_MODE_STRUCTURED        = 2,
+    SHADER_UAV_ACCESS_MODE_RESIZABLE         = 3,
+}
+SHADER_UAV_ACCESS_MODE;
+
+typedef enum SHADER_HW_ACCESS_MODE
+{
+    SHADER_HW_ACCESS_MODE_REGISTER           = 0,
+    SHADER_HW_ACCESS_MODE_MEMORY             = 1
+}
+SHADER_HW_ACCESS_MODE;
+
+typedef enum SHADER_HW_MEM_ACCESS_MODE
+{
+    SHADER_HW_MEM_ACCESS_MODE_PLACE_HOLDER   = 0,
+    SHADER_HW_MEM_ACCESS_MODE_DIRECT_MEM_ADDR= 1,
+    SHADER_HW_MEM_ACCESS_MODE_DIRECT_SAMPLER = 2,
+    SHADER_HW_MEM_ACCESS_MODE_SRV            = 3,
+    SHADER_HW_MEM_ACCESS_MODE_UAV            = 4,
+}
+SHADER_HW_MEM_ACCESS_MODE;
+
+typedef enum SHADER_TESSELLATOR_DOMAIN_TYPE
+{
+    SHADER_TESSELLATOR_DOMAIN_ISOLINE        = 0,
+    SHADER_TESSELLATOR_DOMAIN_TRIANGLE       = 1,
+    SHADER_TESSELLATOR_DOMAIN_QUAD           = 2
+} SHADER_TESSELLATOR_DOMAIN_TYPE;
+
+typedef enum SHADER_TESSELLATOR_PARTITION_TYPE
+{
+    SHADER_TESSELLATOR_PARTITION_INTEGER         = 0,
+    SHADER_TESSELLATOR_PARTITION_POW2            = 1,
+    SHADER_TESSELLATOR_PARTITION_FRACTIONAL_ODD  = 2,
+    SHADER_TESSELLATOR_PARTITION_FRACTIONAL_EVEN = 3
+}
+SHADER_TESSELLATOR_PARTITION_TYPE;
+
+typedef enum SHADER_TESSELLATOR_OUTPUT_PRIMITIVE_TOPOLOGY
+{
+    SHADER_TESSELLATOR_OUTPUT_PRIM_POINT         = 0,
+    SHADER_TESSELLATOR_OUTPUT_PRIM_LINE          = 1,
+    SHADER_TESSELLATOR_OUTPUT_PRIM_TRIANGLE_CW   = 2,
+    SHADER_TESSELLATOR_OUTPUT_PRIM_TRIANGLE_CCW  = 3
+} SHADER_TESSELLATOR_OUTPUT_PRIMITIVE_TOPOLOGY;
+
+typedef enum SHADER_GS_INPUT_PRIMITIVE_TOPOLOGY
+{
+    SHADER_GS_INPUT_PRIMITIVE_POINT              = 0,
+    SHADER_GS_INPUT_PRIMITIVE_LINE               = 1,
+    SHADER_GS_INPUT_PRIMITIVE_TRIANGLE           = 2,
+    SHADER_GS_INPUT_PRIMITIVE_LINE_ADJ           = 3,
+    SHADER_GS_INPUT_PRIMITIVE_TRIANGLE_ADJ       = 4,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_1            = 5,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_2            = 6,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_3            = 7,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_4            = 8,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_5            = 9,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_6            = 10,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_7            = 11,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_8            = 12,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_9            = 13,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_10           = 14,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_11           = 15,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_12           = 16,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_13           = 17,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_14           = 18,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_15           = 19,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_16           = 20,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_17           = 21,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_18           = 22,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_19           = 23,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_20           = 24,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_21           = 25,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_22           = 26,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_23           = 27,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_24           = 28,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_25           = 29,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_26           = 30,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_27           = 31,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_28           = 32,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_29           = 33,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_30           = 34,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_31           = 35,
+    SHADER_GS_INPUT_PRIMITIVE_PATCH_32           = 36,
+} SHADER_GS_INPUT_PRIMITIVE_TOPOLOGY;
+
+typedef enum SHADER_GS_OUTPUT_PRIMITIVE_TOPOLOGY
+{
+    SHADER_GS_OUTPUT_PRIMITIVE_POINTLIST         = 0,
+    SHADER_GS_OUTPUT_PRIMITIVE_LINESTRIP         = 1,
+    SHADER_GS_OUTPUT_PRIMITIVE_TRIANGLESTRIP     = 2,
+}SHADER_GS_OUTPUT_PRIMITIVE_TOPOLOGY;
+
+typedef enum SHADER_IO_MODE
+{
+    /* For inputs of HS/DS/GS, per-prim of HS, and per-prim of DS if it includes
+       per-prim input other than domain-location, they must be set to be active
+       mode, for outputs of PS and per-prim of GS, they must be set to passive mode,
+       for others, they can be any of two */
+    SHADER_IO_MODE_PASSIVE                       = 0,
+    SHADER_IO_MODE_ACTIVE                        = 1,
+}SHADER_IO_MODE;
+
+/* These are only used for active mode */
+typedef enum SHADER_IO_MEM_ALIGN
+{
+    SHADER_IO_MEM_ALIGN_4_CHANNELS               = 0,
+
+    /* This pack is not io-pack designated by packedIoIndexMask. This is a mem
+       alignment pack both for unpacked io or packed io. For example, o0 and o1
+       is packed together into o0, but not packed with o2, but in memory, this
+       packed o0 can be still be packed with o2. */
+    SHADER_IO_MEM_ALIGN_PACKED                   = 1,
+}SHADER_IO_MEM_ALIGN;
+
+typedef enum SHADER_IO_CATEGORY
+{
+    SHADER_IO_CATEGORY_PER_VTX_PXL               = 0,
+    SHADER_IO_CATEGORY_PER_PRIM                  = 1,
+}SHADER_IO_CATEGORY;
+
+/* IO mapping table definitions, for v# and o#
+
+   They are used to HW-level linkage programming. For DX9, such linking will alway
+   use usage and usage index, but for others clients, it will use ioIndex (ioIndex
+   of peers must be same) for most IOs, and usage and usage index for special IOs,
+   such as frontface and pointsize, etc.
+
+   Note that, each shader thread works on specific object, such as vertex/pixel/patch.
+   Some of objects are composed by multiple other sub-objects, for example, a patch is
+   composed by multiple CPs, so such invocation for patch will need per-patch IO and
+   per-CP IO, SHADER_IO_MAPPING_PER_EXE_OBJ reflects this situation.
+*/
+
+#define SPECIAL_HW_IO_REG_NO           0xFFFFFFFE
+typedef struct SHADER_IO_CHANNEL_MAPPING
+{
+    struct
+    {
+        /* This channel is active within shader */
+        gctUINT                                 bActiveWithinShader     : 1;
+
+        /* This IO channel is declared by 'DCL' instruction, DX only */
+        gctUINT                                 bDeclared               : 1;
+
+        /* PS input only, get attributes directly from heading vertex */
+        gctUINT                                 bConstInterpolate       : 1;
+
+        /* PS input only, interpolate is from centroid, not pixel center */
+        gctUINT                                 bCentroidInterpolate    : 1;
+
+        /* PS input only, need (v#/RHW) */
+        gctUINT                                 bPerspectiveCorrection  : 1;
+
+        /* PS input only, for MSAA's subpixel rendering */
+        gctUINT                                 bSampleFrequency        : 1;
+
+        /* PS input only, indicate the input has integer data type. It is
+           only valid when bHighPrecisionOnDual16 is FALSE on dual16 mode */
+        gctUINT                                 bInteger                : 1;
+
+        /* PS only, for high-precision io when executing on dual16 mode */
+        gctUINT                                 bHighPrecisionOnDual16  : 1;
+
+        /* Pre-RA shder stages output only, for stream output */
+        gctUINT                                 bStreamOutToBuffer      : 1;
+
+        /* Reserved bits */
+        gctUINT                                 reserved                : 23;
+    } flag;
+
+    /* Usage of this channel, it will be initialized to SHADER_IO_USAGE_GENERAL at first */
+    SHADER_IO_USAGE                             ioUsage;
+
+    /* For DX9, it may be greater than 0, but for otherwise, almost all are always 0 */
+    gctUINT                                     usageIndex;
+
+    struct
+    {
+        struct
+        {
+            union
+            {
+                /* HW loc number this IO channel is colored to. A channel of same 4-tuple IO register
+                   may be colored to different HW loc when this channel is SVs. For channels other than
+                   SVs, they must be colored into same hwLoc. Also, when passive mode, for some of SVs,
+                   some of HW arch may use special HW reg to reference them, such as frontface/instanceid/
+                   vertexid/..., if so, this member will be set to SPECIAL_HW_IO_REG_NO */
+
+                /* Used for passive mode */
+                gctUINT                         hwRegNo;
+
+                /* Used for active mode. Note this channel loc has different value for different io mem
+                   alignment */
+                gctUINT                         hwChannelLoc;
+            } u;
+
+            /* HW reg channel this IO channel is colored to. The basic rule of HW channel is total HW
+               channel mask of hwRegNo must be 0001(x), 0011(xy), 0111(xyz), or 1111(xyzw) even though
+               some sub-channels of them are inactive, which is the requirement of HW design since our
+               HW can not support per-channel or channel shift register programming. Besides above basic
+               rule, there are different requirements for different shader stages.
+               1. VS input and PS output:
+
+                  Since such IO is connected to memory of fixed function unit, we can not arbitarily
+                  allocate HW channel, it must conform to data element layout/format (ioChannelMask
+                  indicates full/partial of such layout) in memory of FFU unless driver changes data
+                  element of FFU with new layout/format, but such changing is not necessary. For example,
+                  if ioChannelMask is 0110(yz) or 0101(xz), HW reg channel mask must be 0111(xyz), i.e,
+                  must start from x and hole retains, meanwhile, x is mapped to x, y is mapped to y, and
+                  so on. But for masked out channels in ioChannelMask, hwRegChannel may be garbage.
+
+                  If the IO is packed with others, as driver must merge multiple FFU data elements with
+                  different layout/format to new data element of FFU with new layout/format, IO channel
+                  can be mapped to HW channel arbitarily depending on where this channel will be merged.
+                  For example, yz and XZ may be merged to XyZz or XyzZ. Driver needs use ioChannelMask
+                  and hwRegChannel to analyze and generate such merged memory data element of FFU.
+
+               2. I/O among shaders:
+                  Whatever packed or not, as the element layout is fully handled by shader internally, IO
+                  channel can be theoretically mapped to HW channel arbitarily as long as HW register
+                  footprint are diminished. But current compiler implementation still uses same solution
+                  as 1 for unpacked case.
+
+                  When doing HW linkage, for packed case, in addition to do general check, such as usage
+                  and usage index, or ioIndex, we also need check whether same channel of same IO is packed
+                  into same HW channel.
+            */
+            gctUINT8                            hwRegChannel;
+        } cmnHwLoc;
+
+        /* ONLY valid when bHighPrecisionOnDual16 is TRUE. It designates hw-reg-no and hw-reg-channel for
+           T1 hw-thread. */
+        struct
+        {
+            /* For input,
+                  1. a next (successive) hw-reg of cmnHwLoc.u.hwRegNo will be used if corresponding SHADER_IO_REG
+                     has more than 2 channels used, or
+                  2. hw-reg same as cmnHwLoc.u.hwRegNo will be used if corresponding SHADER_IO_REG has less-equal
+                     2 channels used
+               For output, any hw reg except cmnHwLoc.u.hwRegNo can be used */
+            gctUINT                             hwRegNo;
+
+            /* If uses an extra hw-reg against cmnHwLoc.u.hwRegNo, then same cmnHwLoc.hwRegChannel will be used,
+               otherwise a different channel against cmnHwLoc.hwRegChannel will be used */
+            gctUINT8                            hwRegChannel;
+        } t1HwLoc;
+
+    } hwLoc;
+}
+SHADER_IO_CHANNEL_MAPPING;
+
+struct _SHADER_IO_REG_MAPPING
+{
+    SHADER_IO_CHANNEL_MAPPING                   ioChannelMapping[CHANNEL_NUM];
+
+    /* It is the same as index of ioRegMapping which owns it */
+    gctUINT                                     ioIndex;
+
+    /* Which channels are active, corresponding to bActiveWithinShader */
+    gctUINT                                     ioChannelMask;
+
+    /* First valid channel based on io channel mask */
+    gctUINT                                     firstValidIoChannel;
+
+    /* Indicate which IOs are packed with this IO. Channels of all IOs other than
+       SVs that are packed together share same hwRegNo, otherwise, each IO must be
+       colored to different hwRegNo for non-SV channels */
+    gctUINT64                                   packedIoIndexMask;
+
+    /* Indicate which buffer this output reg will stream to, only for streamout. If
+       it is valid, this output must be masked in soIoIndexMask and bStreamOutToBuffer
+       of one of channels of this output reg must be TRUE */
+    gctUINT                                     soStreamBufferSlot;
+
+    /* When streaming to soStreamBufferSlot, what sequence index for this output reg */
+    gctUINT                                     soSeqInStreamBuffer;
+
+    /* Reg io-mode. NOTE that this reg io-mode might be different with io mode defined
+       in SHADER_IO_MAPPING_PER_EXE_OBJ, see comments in that structure */
+    SHADER_IO_MODE                              regIoMode;
+};
+
+typedef struct USAGE_2_IO
+{
+    /* Which Io index is used by this usage on usageindex 0 */
+    gctUINT                                     mainIoIndex;
+
+    /* Which channels are used by this usage on usageindex 0 */
+    gctUINT                                     mainIoChannelMask;
+
+    /* First valid channel based on channel mask on usageindex 0 */
+    gctUINT                                     mainFirstValidIoChannel;
+
+    /* Masked due to different usageIndex */
+    gctUINT64                                   ioIndexMask;
+
+    /* Mask of usageIndex */
+    gctUINT                                     usageIndexMask;
+}
+USAGE_2_IO;
+
+typedef struct SHADER_IO_MAPPING_PER_EXE_OBJ
+{
+    /* IO regs */
+    SHADER_IO_REG_MAPPING*                      pIoRegMapping;
+
+    /* Number of IO regs allocated for pIoRegMapping. Can not be greater than
+       MAX_SHADER_IO_NUM. It must be (maxUsed# + 1). Hole is permitted. */
+    gctUINT                                     countOfIoRegMapping;
+
+    /* Indicate which IO regs are used */
+    gctUINT64                                   ioIndexMask;
+
+    /* Which IO regs are used by each usage */
+    USAGE_2_IO                                  usage2IO[SHADER_IO_USAGE_TOTAL_COUNT];
+
+    /* Pre-RA shader stages output only, for stream output */
+    gctUINT64                                   soIoIndexMask;
+
+    /* Io mode. Note that it is global io-mode for whole exe-obj, sometimes, some of
+       special io-reg have different io-mode against this global io-mode, we need take
+       that reg-io mode (ioRegMode) as precedence. This global mode is only use to do
+       coarse check in hw linker. Note that if the case that global io mode is different
+       with reg-io mode, this global io mode MUST be active mode!!! */
+    SHADER_IO_MODE                              ioMode;
+
+    /* Io memory alignment, only valid when ioMode is SHADER_IO_MODE_ACTIVE */
+    SHADER_IO_MEM_ALIGN                         ioMemAlign;
+
+    /* Io catetory for exe obj */
+    SHADER_IO_CATEGORY                          ioCategory;
+}
+SHADER_IO_MAPPING_PER_EXE_OBJ;
+
+typedef struct SHADER_IO_MAPPING
+{
+    /* Per vertex or pixel object IOs. For multiple vertex or pixel case, each vertex has same info, so we don't
+       need record all elements of such object array. The size of this array is got from SHADER_EXECUTABLE_NATIVE_HINTS.
+       Note that this object array can be indexed by per-object index. */
+    SHADER_IO_MAPPING_PER_EXE_OBJ               ioVtxPxl;
+
+    /* Per primitive object IOs which may includes multiple vertex or pixel object. Currently, it is only be used
+       for HS/DS/GS shaders */
+    SHADER_IO_MAPPING_PER_EXE_OBJ               ioPrim;
+}
+SHADER_IO_MAPPING;
+
+/* Constant mapping table definitions, for c#/i#/b#/cb#/icb#
+
+   They are used to update constant values
+*/
+
+typedef enum SHADER_CONSTANT_OFFSET_KIND
+{
+    SHADER_CONSTANT_OFFSET_IN_BYTE      = 0,
+    SHADER_CONSTANT_OFFSET_IN_ARRAY     = 1,
+} SHADER_CONSTANT_OFFSET_KIND;
+
+typedef struct _SHADER_CONSTANT_HW_LOCATION_MAPPING SHADER_CONSTANT_HW_LOCATION_MAPPING;
+struct _SHADER_CONSTANT_HW_LOCATION_MAPPING
+{
+    SHADER_HW_ACCESS_MODE                            hwAccessMode;
+
+    union
+    {
+        /* Case to map to constant register */
+        struct
+        {
+            gctUINT                                  hwRegNo;
+            gctUINT                                  hwRegRange;
+        } constReg;
+
+        /* Case to map to constant memory
+
+           CAUTION for memory layout:
+           1. For non-CTC spilled mem, currently, memory layout is designed to 4-tuples based as
+              constant register,that means every element of scalar/vec2~4 array will be put into
+              separated room of 4-tuples. With such layout design, we can support both DX1x cb#/icb#
+              and GL named uniform block. So offset must be at 4-tuples alignment.
+
+              But GL named uniform block has more loose layout requirement based on spec (for example,
+              there could be no padding between any pair of GL type of data, but it is unfriendly
+              for DX), so HW may design a different layout requirement for constant buffer, or directly
+              use similar ld as GPGPU uses. If so, we should re-design followings and their users.
+
+           2. For CTC spilled mem, first channel might be started at any location, even might be started
+              at part of one channle(FP16/UINT16/INT16), so we can't use offset in array, we need
+              to use offset in byte directly. And in this case, firstValidHwChannel must
+              be started at X-channel which is located at constantOffset.
+        */
+        struct
+        {
+            SHADER_HW_MEM_ACCESS_MODE                hwMemAccessMode;
+
+            union
+            {
+                /* For place-holder # case */
+                gctUINT                              hwConstantArraySlot;
+
+                /* For direct mem address case, if it is used for vulkan resources table maintained
+                   by PEP, PEP generator will allocate/free it; if it is used for SEP, just pointing
+                   to field of SHADER_CONSTANT_HW_LOCATION_MAPPING of one of entry of constant array
+                   table. The pHwDirectAddrBase::hwAccessMode must be SHADER_HW_ACCESS_MODE_REGISTER */
+                SHADER_CONSTANT_HW_LOCATION_MAPPING* pHwDirectAddrBase;
+
+                /* For the case that constant array is mapped to SRV, if it is used for vulkan resources
+                   table maintained by PEP, PEP generator will allocate/free it; if it is used for SEP,
+                   just pointing to one of entry of SRV table */
+                SHADER_RESOURCE_SLOT_MAPPING*        pSrv;
+
+                /* For the case that constant array is mapped to UAV, if it is used for vulkan resources
+                   table maintained by PEP, PEP generator will allocate/free it; if it is used for SEP,
+                   just pointing to one of entry of UAV table */
+                SHADER_UAV_SLOT_MAPPING*             pUav;
+            } memBase;
+
+            /* At channel boundary. See CAUTION!! */
+            SHADER_CONSTANT_OFFSET_KIND              constantOffsetKind;
+            gctUINT                                  constantOffset;
+            gctUINT                                  componentSizeInByte;
+        } memAddr;
+    } hwLoc;
+
+    /* Which channels of this HW location are valid for this 4-tuples constant */
+    gctUINT                                          validHWChannelMask;
+
+    /* First valid channel based on validHWChannelMask */
+    gctUINT                                          firstValidHwChannel;
+};
+
+struct _SHADER_CONSTANT_SUB_ARRAY_MAPPING
+{
+    /* Start and size of sub array. 'startIdx' is the index within 'arrayRange' of parent */
+    gctUINT                                     startIdx;
+    gctUINT                                     subArrayRange;
+
+    /* Only used by DX, for DX10+, it is the 2nd dimension of cb/icb, otherwise, it is 1st dimension */
+    gctUINT                                     firstMSCSharpRegNo;
+
+    /* Which channels are valid for this 4-tuples constant sub array. Note that mapping from validChannelMask
+       to validHWChannelMask is not channel-based, so hole is supported. For example, 0011(xy) may be mapped
+       to 0011(xy), 0110(yz) or 1100(zw), but 0101(xz) can only be mapped to 0111(xyz) or 1110(yzw) */
+    gctUINT                                     validChannelMask;
+
+    /* HW constant location for first element of this array.
+       Note that all elements in each sub-array must have same channel mask designated by validChannelMask
+       and validHWChannelMask respectively */
+    SHADER_CONSTANT_HW_LOCATION_MAPPING         hwFirstConstantLocation;
+};
+
+typedef struct SHADER_CONSTANT_ARRAY_MAPPING
+{
+    /* It is the same as index of pConstantArrayMapping which owns it */
+    gctUINT                                     constantArrayIndex;
+
+    SHADER_CONSTANT_USAGE                       constantUsage;
+
+    /* Array size, including all sub-arrays it holds */
+    gctUINT                                     arrayRange;
+
+    /* For 2 purposes, we need split constant buffer into several subs
+       1. Not all constant registers are used in constant buffer or a big uniform for OGL, so each
+          used part can be put into a sub
+       2. OGL may have many uniforms, each may be put into different sub if they can be put together
+
+       So there is a possibility that several sub constant arrays share same startIdx and subArrayRange
+       with different validChannelMask, also there is a possibility that several sub constant arrays
+       share same HW reg/mem with different validHWChannelMask */
+    SHADER_CONSTANT_SUB_ARRAY_MAPPING*          pSubConstantArrays;
+    gctUINT                                     countOfSubConstantArray;
+}
+SHADER_CONSTANT_ARRAY_MAPPING;
+
+struct _SHADER_COMPILE_TIME_CONSTANT
+{
+    gctUINT                                     constantValue[CHANNEL_NUM];
+
+    /* HW constant location that this CTC maps to. Just use validHWChannelMask to indicate which channels
+       have an immedidate CTC value */
+    SHADER_CONSTANT_HW_LOCATION_MAPPING         hwConstantLocation;
+};
+
+typedef struct SHADER_CONSTANT_MAPPING
+{
+    /* Constant buffer arrays */
+    SHADER_CONSTANT_ARRAY_MAPPING*              pConstantArrayMapping;
+
+    /* Number of constant buffer arrays allocated for pConstantArrayMapping. Can not be greater than
+       MAX_SHADER_CONSTANT_ARRAY_NUM. It must be (maxUsed# + 1). Hole is permitted. */
+    gctUINT                                     countOfConstantArrayMapping;
+
+    /* Indicate which arrays are used */
+    gctUINT                                     arrayIndexMask;
+
+    /* Only used for DX9, no meaning for other clients */
+    gctUINT                                     usage2ArrayIndex[SHADER_CONSTANT_USAGE_TOTAL_COUNT];
+
+    /* Compiling-time immediate values */
+    SHADER_COMPILE_TIME_CONSTANT*               pCompileTimeConstant;
+    gctUINT                                     countOfCompileTimeConstant;
+
+    /* HW constant register count that machine shader uses, i.e, only consider constants that have
+       SHADER_HW_ACCESS_MODE_REGISTER access mode. It is equal to (max-used-const-regNo + 1). This
+       is similiar as gprCount. */
+    gctUINT                                     hwConstRegCount;
+
+    /* Max HW constant register index that machine shader users, the default value is -1. */
+    gctINT                                      maxHwConstRegIndex;
+}
+SHADER_CONSTANT_MAPPING;
+
+/* Sampler mapping table definitions for s#
+
+   They are used to update sampler state
+*/
+
+struct _SHADER_SAMPLER_SLOT_MAPPING
+{
+    /* It is the same as index of sampler which owns it */
+    gctUINT                                     samplerSlotIndex;
+
+    /* It does not apply to DX1x, and it will be removed after HW supports separated t# */
+    SHADER_RESOURCE_DIMENSION                   samplerDimension;
+
+    /* Only for OGL(ES). Return type by sample/ld inst, and it will be removed after HW
+       supports separated t# */
+    SHADER_RESOURCE_RETURN_TYPE                 samplerReturnType;
+
+    /* Sampler mode, DX1x only */
+    SHADER_SAMPLER_MODE                         samplerMode;
+
+    /* HW slot number */
+    gctUINT                                     hwSamplerSlot;
+};
+
+typedef struct SHADER_SAMPLER_MAPPING
+{
+    SHADER_SAMPLER_SLOT_MAPPING*                pSampler;
+
+    /* Number of samplers allocated for pSampler. Can not be greater than
+       MAX_SHADER_SAMPLER_NUM. It must be (maxUsed# + 1). Hole is permitted.
+    */
+    gctUINT                                     countOfSamplers;
+
+    /* Indicate which samplers are used */
+    gctUINT                                     samplerSlotMask;
+
+    /* It does not apply to DX1x, and it will be removed after HW supports separated t# */
+    gctUINT                                     dim2SamplerSlotMask[SHADER_RESOURCE_DIMENSION_TOTAL_COUNT];
+
+    /* HW sampler register count that machine shader uses. */
+    gctUINT                                     hwSamplerRegCount;
+
+    /* Max HW sampler register index that machine shader users, the default value is -1. */
+    gctINT                                      maxHwSamplerRegIndex;
+}
+SHADER_SAMPLER_MAPPING;
+
+/* Shader resource mapping table definitions for t#
+
+   They are used to update shader resource state
+*/
+
+struct _SHADER_RESOURCE_SLOT_MAPPING
+{
+    /* It is the same as index of resource which owns it */
+    gctUINT                                     resourceSlotIndex;
+
+    SHADER_RESOURCE_ACCESS_MODE                 accessMode;
+
+    union
+    {
+        /* For type of access mode */
+        struct
+        {
+            /* It only applies to DX1x */
+            SHADER_RESOURCE_DIMENSION           resourceDimension;
+
+            /* Resource return type by sample/ld inst */
+            SHADER_RESOURCE_RETURN_TYPE         resourceReturnType;
+        } s;
+
+        /* For structured of access mode */
+        gctUINT                                 structureSize;
+    } u;
+
+    /* HW slot number */
+    gctUINT                                     hwResourceSlot;
+};
+
+typedef struct SHADER_RESOURCE_MAPPING
+{
+    SHADER_RESOURCE_SLOT_MAPPING*               pResource;
+
+    /* Number of resources allocated for pResource. Can not be greater than
+       MAX_SHADER_RESOURCE_NUM. It must be (maxUsed# + 1). Hole is permitted. */
+    gctUINT                                     countOfResources;
+
+    /* Indicate which resources are used */
+    gctUINT                                     resourceSlotMask[4];
+
+    /* It only applies to DX1x for typed access mode */
+    gctUINT                                     dim2ResourceSlotMask[SHADER_RESOURCE_DIMENSION_TOTAL_COUNT][4];
+}
+SHADER_RESOURCE_MAPPING;
+
+/* Global memory mapping table definitions for u#
+
+   They are used to update global memory state, such as UAV
+*/
+
+struct _SHADER_UAV_SLOT_MAPPING
+{
+    /* It is the same as index of UAV which owns it */
+    gctUINT                                     uavSlotIndex;
+
+    SHADER_UAV_ACCESS_MODE                      accessMode;
+    SHADER_HW_MEM_ACCESS_MODE                   hwMemAccessMode;
+
+    /* There are two following reasons for this. The default is 0.
+       1. For compiler internally generated UAVs (for patch for the most of cases), we need tell driver
+          the total flattened UAV size, so driver can allocate it on vid-mem.
+       2 .For sizable access mode, we need know the size of fixed size part.
+    */
+    gctUINT                                     sizeInByte;
+    /* HW slot number, now only some inputAttachment uses this variable.  */
+    gctUINT                                     hwSamplerSlot;
+
+    union
+    {
+        /* For type of access mode */
+        struct
+        {
+            /* It only applies to DX1x */
+            SHADER_UAV_DIMENSION                uavDimension;
+
+            /* UAV return type by ld/store inst */
+            SHADER_UAV_TYPE                     uavType;
+        } s;
+
+        /* For resizable access mode */
+        gctUINT                                 sizableEleSize;
+
+        /* For structured of access mode */
+        gctUINT                                 structureSize;
+    } u;
+
+    union
+    {
+        /* For place-holder # case */
+        gctUINT                                 hwUavSlot;
+
+        /* For direct mem address case, if it is used for vulkan resources table maintained
+           by PEP, PEP generator will allocate/free it; if it is used for SEP, just pointing
+           to field of SHADER_CONSTANT_HW_LOCATION_MAPPING of one of entry of constant array
+           table. The pHwDirectAddrBase::hwAccessMode must be SHADER_HW_ACCESS_MODE_REGISTER */
+        SHADER_CONSTANT_HW_LOCATION_MAPPING*    pHwDirectAddrBase;
+    } hwLoc;
+};
+
+typedef struct SHADER_UAV_MAPPING
+{
+    SHADER_UAV_SLOT_MAPPING*                    pUAV;
+
+    /* Number of UAVs allocated for pUAV. Can not be greater than
+       MAX_SHADER_UAV_NUM. It must be (maxUsed# + 1). Hole is permitted. */
+    gctUINT                                     countOfUAVs;
+
+    /* Indicate which UAVs are used */
+    gctUINT                                     uavSlotMask;
+
+    /* It only applies to DX1x for typed access mode */
+    gctUINT                                     dim2UavSlotMask[SHADER_UAV_DIMENSION_TOTAL_COUNT];
+}
+SHADER_UAV_MAPPING;
+
+/* For these hints, they must be natively provided by original shader or shader owner, such as HS/DS/GS,
+   there are special hints for them, such as vertex/pixel/CP (sub executable object) count and tessellation
+   mode for patch primitive, etc */
+typedef struct SHADER_EXECUTABLE_NATIVE_HINTS
+{
+    struct
+    {
+        /* DX ony. Precision consideration, it is a global flag. 'precise' is a local flag */
+        gctUINT                                          bRefactorable    : 1;
+
+        /* For GL(ES), it can be set TRUE or FALSE, for others, it must be set to TRUE */
+        gctUINT                                          bSeparatedShader : 1;
+
+        /* For GL(ES), it can be set TRUE or FALSE, for others, it must be set to FALSE */
+        gctUINT                                          bLinkProgramPipeline : 1;
+
+        /* What kind of memory access operations shader native holds, see SHADER_EDH_MEM_ACCESS_HINT */
+        gctUINT                                          memoryAccessHint  : 6;
+
+        gctUINT                                          flowControlHint   : 3;
+
+        gctUINT                                          texldHint         : 1;
+
+        gctUINT                                          reserved          : 19;
+    } globalStates;
+
+    union
+    {
+        /* States acted on HS/DS. The primitive processing must be a patch.
+           HS/DS share same states because part of them is put different shader for DX and GL.
+        */
+        struct
+        {
+            gctUINT                                      inputCtrlPointCount;
+
+            /* HS only */
+            gctUINT                                      outputCtrlPointCount;
+
+            /* For DX, they are provided in HS, but for OGL they are provided in DS */
+            SHADER_TESSELLATOR_DOMAIN_TYPE               tessDomainType;
+            SHADER_TESSELLATOR_PARTITION_TYPE            tessPartitionType;
+            SHADER_TESSELLATOR_OUTPUT_PRIMITIVE_TOPOLOGY tessOutputPrim;
+            gctUINT                                      maxTessFactor;
+        } ts;
+
+        /* States acted on GS */
+        struct
+        {
+            gctUINT                                      maxOutputVtxCount;
+            gctUINT                                      instanceCount;
+            SHADER_GS_INPUT_PRIMITIVE_TOPOLOGY           inputPrim;
+            SHADER_GS_OUTPUT_PRIMITIVE_TOPOLOGY          outputPrim;
+
+            /* It is retrieved from inputPrim. Standalone providing this is just for convenience only */
+            gctUINT                                      inputVtxCount;
+        } gs;
+
+        /* States acted on PS */
+        struct
+        {
+            /* OGL only */
+            gctUINT                                      bEarlyPixelTestInRa : 1;
+
+            gctUINT                                      reserved            : 31;
+        } ps;
+
+        /* States acted on gps */
+        struct
+        {
+            gctUINT                                      shareMemSizePerThreadGrpInByte;
+            gctUINT                                      currWorkGrpNum;
+
+            gctUINT                                      privMemSizePerThreadInByte;
+            gctUINT                                      currWorkThreadNum;
+
+            gctUINT                                      workGroupNumPerShaderGroup;
+
+            gctUINT                                      threadGrpDimX;
+            gctUINT                                      threadGrpDimY;
+            gctUINT                                      threadGrpDimZ;
+
+            gctUINT                                      calculatedWorkGroupSize;
+        } gps;
+    } prvStates;
+}
+SHADER_EXECUTABLE_NATIVE_HINTS;
+
+typedef enum UNIFIED_RF_ALLOC_STRATEGY
+{
+    /* For current shader type, the start offset and size is fix reserved in unified register file,
+       so address offset will be set to that fixed offset. It is full same as allocating unnified
+       RF because each shader type has its own space */
+    UNIFIED_RF_ALLOC_STRATEGY_FIXED_ADDR_OFFSET                     = 0,
+
+    /* For current shader type, the start offset and size is float (which means not reserved in unified
+       register file). For all implementation, each used RF space will be packed together (that
+       means this address offset is start from end of previous stage's RF resource */
+    UNIFIED_RF_ALLOC_STRATEGY_PACK_FLOAT_ADDR_OFFSET                = 1,
+
+    /* Pack all GPIPE stages together and put them in the top of resource, and put PS in the bottom. */
+    UNIFIED_RF_ALLOC_STRATEGY_GPIPE_TOP_PS_BOTTOM_FLOAT_ADDR_OFFSET = 2,
+
+    /* Pack all GPIPE stages together and put them in the bottom of resource, and put PS in the top. */
+    UNIFIED_RF_ALLOC_STRATEGY_PS_TOP_GPIPE_BOTTOM_FLOAT_ADDR_OFFSET = 3,
+
+    /* When HW provide unified register file (such as const/sampler), for non-seperated compiling
+       for GL(ES), compiler may use different allocation strategy to allocate register in full scope
+       of unified register file for a GL(ES) program. In this case, all shaders in this program
+       should use same strategy. However, For other cases, such as DX/CL/seperated cases of GL(ES),
+       they can not use UNIFIED_RF_ALLOC_STRATEGY_UNIFIED because there are no program concept.
+
+       !!!NOTE that driver need assure it won not mix shaders belonging to different non-seperated
+          programs to do programming. Otherwise, result is undefined!!!! */
+
+    /* Allocated in full scope of unified register file, so address offset will be set to zero */
+    UNIFIED_RF_ALLOC_STRATEGY_UNIFIED                               = 4,
+}
+UNIFIED_RF_ALLOC_STRATEGY;
+
+/* Shader mem access hints for executable-derived-hints */
+typedef enum SHADER_EDH_MEM_ACCESS_HINT
+{
+    SHADER_EDH_MEM_ACCESS_HINT_NONE               = 0x0000,
+    SHADER_EDH_MEM_ACCESS_HINT_LOAD               = 0x0001,
+    SHADER_EDH_MEM_ACCESS_HINT_STORE              = 0x0002,
+    SHADER_EDH_MEM_ACCESS_HINT_IMG_READ           = 0x0004,
+    SHADER_EDH_MEM_ACCESS_HINT_IMG_WRITE          = 0x0008,
+    SHADER_EDH_MEM_ACCESS_HINT_ATOMIC             = 0x0010,
+
+    SHADER_EDH_MEM_ACCESS_HINT_READ               = SHADER_EDH_MEM_ACCESS_HINT_LOAD       |
+                                                    SHADER_EDH_MEM_ACCESS_HINT_IMG_READ   |
+                                                    SHADER_EDH_MEM_ACCESS_HINT_ATOMIC,
+    SHADER_EDH_MEM_ACCESS_HINT_WRITE              = SHADER_EDH_MEM_ACCESS_HINT_STORE      |
+                                                    SHADER_EDH_MEM_ACCESS_HINT_IMG_WRITE  |
+                                                    SHADER_EDH_MEM_ACCESS_HINT_ATOMIC,
+
+    SHADER_EDH_MEM_ACCESS_HINT_BARRIER            = 0x0020,
+    SHADER_EDH_MEM_ACCESS_HINT_EVIS_ATOMADD       = 0x0040, /* evis atomadd can operate on 16B data in parallel,
+                                                             * we need to tell driver to turn off workgroup packing
+                                                             * if it is used so the HW will not merge different
+                                                             * workgroup into one which can cause the different
+                                                             * address be used for the evis_atom_add */
+/* Note: 1. must sync with VIR_MemoryAccessFlag !!!
+ *       2. make sure it fits in bits in SHADER_EXECUTABLE_DERIVED_HINTS::memoryAccessHint */
+}SHADER_EDH_MEM_ACCESS_HINT;
+
+/* Shader flow control hints for executable-derived-hints */
+typedef enum SHADER_EDH_FLOW_CONTROL_HINT
+{
+    SHADER_EDH_FLOW_CONTROL_HINT_NONE             = 0x0000,
+    SHADER_EDH_FLOW_CONTROL_HINT_JMP              = 0x0001,
+    SHADER_EDH_FLOW_CONTROL_HINT_CALL             = 0x0002,
+    SHADER_EDH_FLOW_CONTROL_HINT_KILL             = 0x0004,
+/* Note: 1. must sync with VIR_FlowControlFlag !!!
+ *       2. make sure it fits in bits in SHADER_EXECUTABLE_DERIVED_HINTS::flowControlHint */
+}SHADER_EDH_FLOW_CONTROL_HINT;
+
+/* Shader texture hints for executable-derived-hints */
+typedef enum SHADER_EDH_TEXLD_HINT
+{
+    SHADER_EDH_TEXLD_HINT_NONE             = 0x0000,
+    SHADER_EDH_TEXLD_HINT_TEXLD            = 0x0001,
+/* Note: 1. must sync with VIR_TexldFlag !!!
+ *       2. make sure it fits in bits in SHADER_EXECUTABLE_DERIVED_HINTS::texldHint */
+}SHADER_EDH_TEXLD_HINT;
+
+/* For these hints, we can retrieve them by analyzing machine code on the fly, but it will
+   hurt perf, so collect them by analyzing (derived) directly from compiler. */
+typedef struct SHADER_EXECUTABLE_DERIVED_HINTS
+{
+    struct
+    {
+        /************************************/
+        /* Followings are MUST global hints */
+        /************************************/
+
+        /* Shader will run on dual16 mode */
+        gctUINT                   bExecuteOnDual16                : 1;
+
+        /* Unified constant register file alloc strategy. For ununified RF, it has no mean */
+        gctUINT                   unifiedConstRegAllocStrategy    : 3;
+
+        /* Unified sampler register file alloc strategy. For ununified RF, it has no mean */
+        gctUINT                   unifiedSamplerRegAllocStrategy  : 3;
+
+        /* Whether the shader has GPR register spills */
+        gctUINT                   bGprSpilled                     : 1;
+
+        /* Whether the shader has constant register spills */
+        gctUINT                   bCrSpilled                      : 1;
+
+        /****************************************/
+        /* Followings are OPTIONAL global hints */
+        /****************************************/
+
+        /* What kind of memory access operations shader holds, see SHADER_EDH_MEM_ACCESS_HINT */
+        gctUINT                   memoryAccessHint                : 8;
+
+        /* What kind of flow control operations shader holds, see SHADER_EDH_FLOW_CONTROL_HINT */
+        gctUINT                   flowControlHint                 : 3;
+
+        /* What kind of texld operations shader holds, see SHADER_EDH_TEXLD_HINT */
+        gctUINT                   texldHint                       : 1;
+
+        /* First HW reg and its channel that will be used to store addresses
+           of USC for each vertex when executing hs/ds/gs. */
+        gctUINT                   hwStartRegNoForUSCAddrs         : 4;
+        gctUINT                   hwStartRegChannelForUSCAddrs    : 2;
+
+        /* Address in USC for input and output vertex/CP are packed into one
+           HW reg, NOTE that it is only used when vertex/CP count of input and
+           output are all LE 4 */
+        gctUINT                   bIoUSCAddrsPackedToOneReg       : 1;
+
+        /* Whether enable multi-GPU. */
+        gctUINT                   bEnableMultiGPU                 : 1;
+
+        /* Whether enable robust out-of-bounds check for memory access . */
+        gctUINT                   bEnableRobustCheck              : 1;
+
+        gctUINT                   reserved                        : 2;
+
+        gctUINT                   gprSpillSize;  /* the byte count of register spill mem to be
+                                                  * allocated by driver in MultiGPU mode*/
+    } globalStates;
+
+    struct
+    {
+        /* Z-channel of output position of pre-RA is dependent on W-channel of that position. This is
+           a special hint to do RA wclip SW patch */
+        gctUINT                   bOutPosZDepW                    : 1;
+
+        gctUINT                   reserved                        : 31;
+    } prePaStates;
+
+    union
+    {
+        /* States acted on HS */
+        struct
+        {
+            /* Whether data of one of output CP are accessed by other output CP threads */
+            gctUINT               bPerCpOutputsUsedByOtherThreads : 1;
+
+            gctUINT               reserved                        : 31;
+        } hs;
+
+        /* States acted on GS */
+        struct
+        {
+            /* Shader has explicit restart operation */
+            gctUINT               bHasPrimRestartOp               : 1;
+
+            gctUINT               reserved                        : 31;
+        } gs;
+
+        /* States acted on PS */
+        struct
+        {
+            /* To determine which io-index of output mapping have alpha write */
+            gctUINT               alphaWriteOutputIndexMask       : 8;
+
+            /* Shader has operation to calc gradient on x/y of RT */
+            gctUINT               bDerivRTx                       : 1;
+            gctUINT               bDerivRTy                       : 1;
+            /* shader has dsy IR before lowering to machine code, so it
+             * wouldn't count fwidth() as using DSY for yInvert purpose */
+            gctUINT               bDsyBeforeLowering              : 1;
+
+            /* Shader has operation to discard pixel (such as texkill/discard) */
+            gctUINT               bPxlDiscard                     : 1;
+
+            /* Under per-sample freq shading, sample-mask-in and sample_index are
+               put in a channel of special reg number by RA, and sample-mask-out
+               will also be written into this channel (bit[0~3]) */
+            gctUINT               hwRegNoForSampleMaskId          : 9;
+            gctUINT               hwRegChannelForSampleMaskId     : 2;
+
+            /* Shader will run on per-sample frequency */
+            gctUINT               bExecuteOnSampleFreq            : 1;
+
+            /* Position and point-coord per-channel valid info. Note we can not use
+               SHADER_IO_REG_MAPPING to check this because it is high-level info, not
+               low-level (HW) info. Directly using SHADER_IO_REG_MAPPIN may get wrong
+               result if high-level channel maps a HW channel that is differnt with
+               high-level channel */
+            gctUINT               inputPosChannelValid            : 4;
+            gctUINT               inputPntCoordChannelValid       : 2;
+
+            /* To determine whether shader needs read RT data (for example, shader
+               implements alpha-blend, or for OGL, lastFragData is presented) */
+            gctUINT               bNeedRtRead                     : 1;
+
+#if gcdALPHA_KILL_IN_SHADER
+            gctUINT               alphaClrKillInstsGened          : 1;
+#else
+            gctUINT               reserved                        : 1;
+#endif
+            gctUINT               fragColorUsage                  : 2;
+        } ps;
+
+        /* States acted on gps */
+        struct
+        {
+            /* Whether whole thread group needs sync */
+            gctUINT               bThreadGroupSync                : 1;
+
+            /* Whether use Local memory. */
+            gctUINT               bUseLocalMemory                 : 1;
+
+            gctUINT               reserved                        : 30;
+
+            gctUINT16             workGroupSizeFactor[3];
+        } gps;
+    } prvStates;
+}SHADER_EXECUTABLE_DERIVED_HINTS;
+
+typedef struct SHADER_EXECUTABLE_HINTS
+{
+    SHADER_EXECUTABLE_NATIVE_HINTS          nativeHints;
+    SHADER_EXECUTABLE_DERIVED_HINTS         derivedHints;
+}SHADER_EXECUTABLE_HINTS;
+
+
+struct SHADER_EXECUTABLE_INSTANCE;
+
+/* Executable shader profile definition. Each BE compiling or glProgramBinary will generate one
+   profile like this. */
+typedef struct SHADER_EXECUTABLE_PROFILE
+{
+    /* Profile version */
+    gctUINT                                     profileVersion;
+
+    /* Target HW this executable can run on */
+    gctUINT                                     chipModel;
+    gctUINT                                     chipRevision;
+    gctUINT                                     productID;
+    gctUINT                                     customerID;
+
+    /* From MSB to LSB, 8-bits client + 8-bits type + 8-bits majorVersion + 8-bits minorVersion */
+    gctUINT                                     shVersionType;
+
+    /* Compiled machine code. Note that current countOfMCInst must be 4-times of DWORD since HW
+       inst is 128-bits wide. It may be changed later for future chip */
+    gctUINT*                                    pMachineCode;
+    gctUINT                                     countOfMCInst;
+
+    /* EndPC of main routine since HW will use it to terminate shader execution. The whole machine
+       code is organized as main routine followed by all sub-routines */
+    gctUINT                                     endPCOfMainRoutine;
+
+    /* Temp register count the machine code uses */
+    gctUINT                                     gprCount;
+
+    /* Special executable hints that this SEP holds. When shader is executed inside of HW, it will
+       rely on this special execute hints */
+    SHADER_EXECUTABLE_HINTS                     exeHints;
+
+    /* Low level mapping tables (mapping pool) from # to HW resource. Add new mapping tables here,
+       for example, function table for DX11+ */
+    SHADER_IO_MAPPING                           inputMapping;
+    SHADER_IO_MAPPING                           outputMapping;
+    SHADER_CONSTANT_MAPPING                     constantMapping;
+    SHADER_SAMPLER_MAPPING                      samplerMapping;
+    SHADER_RESOURCE_MAPPING                     resourceMapping;
+    SHADER_UAV_MAPPING                          uavMapping;
+
+    /* All private mapping tables for static patches. Every entry has a member pointing to a slot in
+       above mapping pool */
+    SHADER_STATIC_PRIV_MAPPING                  staticPrivMapping;
+
+    /* All private mapping tables for dynamic (lib-link) patches. Every entry has a member pointing
+       to a slot in above mapping pool */
+    SHADER_DYNAMIC_PRIV_MAPPING                 dynamicPrivMapping;
+
+    SHADER_DEFAULT_UBO_MAPPING                  defaultUboMapping;
+
+    /* Current SEI that this profile uses. This is the one used to program HW registers. Currently disable it
+       due to we're using program-level recompiling */
+    /*SHADER_EXECUTABLE_INSTANCE*                 pCurInstance;*/
+}
+SHADER_EXECUTABLE_PROFILE;
+
+gceSTATUS vscInitializeSEP(SHADER_EXECUTABLE_PROFILE* pSEP);
+gceSTATUS vscFinalizeSEP(SHADER_EXECUTABLE_PROFILE* pSEP);
+gctBOOL vscIsValidSEP(SHADER_EXECUTABLE_PROFILE* pSEP);
+
+gceSTATUS vscInitializeIoRegMapping(SHADER_IO_REG_MAPPING* pIoRegMapping);
+gceSTATUS vscFinalizeIoRegMapping(SHADER_IO_REG_MAPPING* pIoRegMapping);
+
+gceSTATUS vscInitializeCnstHwLocMapping(SHADER_CONSTANT_HW_LOCATION_MAPPING* pCnstHwLocMapping);
+gceSTATUS vscFinalizeCnstHwLocMapping(SHADER_CONSTANT_HW_LOCATION_MAPPING* pCnstHwLocMapping);
+
+gceSTATUS vscInitializeCTC(SHADER_COMPILE_TIME_CONSTANT* pCompileTimeConstant);
+gceSTATUS vscFinalizeCTC(SHADER_COMPILE_TIME_CONSTANT* pCompileTimeConstant);
+
+gceSTATUS vscInitializeCnstArrayMapping(SHADER_CONSTANT_ARRAY_MAPPING* pCnstArrayMapping);
+gceSTATUS vscFinalizeCnstArrayMapping(SHADER_CONSTANT_ARRAY_MAPPING* pCnstArrayMapping);
+
+gceSTATUS vscInitializeCnstSubArrayMapping(SHADER_CONSTANT_SUB_ARRAY_MAPPING* pCnstSubArrayMapping);
+gceSTATUS vscFinalizeCnstSubArrayMapping(SHADER_CONSTANT_SUB_ARRAY_MAPPING* pCnstSubArrayMapping);
+
+gceSTATUS vscInitializeSamplerSlotMapping(SHADER_SAMPLER_SLOT_MAPPING* pSamplerSlotMapping);
+gceSTATUS vscFinalizeSamplerSlotMapping(SHADER_SAMPLER_SLOT_MAPPING* pSamplerSlotMapping);
+
+gceSTATUS vscInitializeUavSlotMapping(SHADER_UAV_SLOT_MAPPING* pUavSlotMapping);
+gceSTATUS vscFinalizeUavSlotMapping(SHADER_UAV_SLOT_MAPPING* pUavSlotMapping);
+
+void vscSortIOsByHwLoc(SHADER_IO_MAPPING_PER_EXE_OBJ* pIoMappingPerExeObj, gctUINT* pSortedIoIdxArray);
+
+/* If hShader != NULL, mapping 'symbol->#->hw resource' is dumped, otherwise
+   only '#->hw' is dumped. For the 2nd case, it is easy for driver to dump any
+   SEP when flushing to hw to triage bugs */
+void vscPrintSEP(VSC_SYS_CONTEXT* pSysCtx, SHADER_EXECUTABLE_PROFILE* pSEP, SHADER_HANDLE hShader);
+
+/* Linkage info */
+typedef struct SHADER_IO_REG_LINKAGE
+{
+    /* This channel have link by other stage, for linkage */
+    gctBOOL                                     bLinkedByOtherStageX : 2;
+    gctBOOL                                     bLinkedByOtherStageY : 2;
+    gctBOOL                                     bLinkedByOtherStageZ : 2;
+    gctBOOL                                     bLinkedByOtherStageW : 2;
+
+    /* This output is only linked to FFU SO */
+    gctBOOL                                     bOnlyLinkToSO : 2;
+
+    /* This is dummy link, which means it will not be consumed by anyone. It is only used for active-mode IO */
+    gctBOOL                                     bIsDummyLink  : 2;
+
+    /* Used to link to other stage */
+    gctUINT                                     linkNo;
+}SHADER_IO_REG_LINKAGE;
+
+typedef struct SHADER_IO_LINKAGE_INFO_PER_EXE_OBJ
+{
+    SHADER_IO_REG_LINKAGE                       ioRegLinkage[MAX_SHADER_IO_NUM];
+    gctUINT                                     totalLinkNoCount;
+}SHADER_IO_LINKAGE_INFO_PER_EXE_OBJ;
+
+typedef struct SHADER_IO_LINKAGE_INFO
+{
+    SHADER_IO_LINKAGE_INFO_PER_EXE_OBJ          vtxPxlLinkage;
+    SHADER_IO_LINKAGE_INFO_PER_EXE_OBJ          primLinkage;
+
+    /* When linking with other shader, which type of shader is linked to */
+    SHADER_TYPE                                 linkedShaderStage;
+}SHADER_IO_LINKAGE_INFO;
+
+typedef enum HW_INST_FETCH_MODE
+{
+    /* Fetched from non-unified inst buffer, using 0x1000 and 0x1800 */
+    HW_INST_FETCH_MODE_UNUNIFIED_BUFFER        = 0,
+
+    /* Fetched from unified inst buffer 0, using 0x3000 and 0x2000 */
+    HW_INST_FETCH_MODE_UNIFIED_BUFFER_0        = 1,
+
+    /* Fetched from unified inst buffer 1, using 0x8000 */
+    HW_INST_FETCH_MODE_UNIFIED_BUFFER_1        = 2,
+
+    /* Fetched from I$ */
+    HW_INST_FETCH_MODE_CACHE                   = 3,
+}HW_INST_FETCH_MODE;
+
+typedef enum HW_CONSTANT_FETCH_MODE
+{
+    /* Fetched from non-unified constant RF, using 0x1400 and 0x1C00 */
+    HW_CONSTANT_FETCH_MODE_UNUNIFIED_REG_FILE  = 0,
+
+    /* Fetched from unified constant RF, using 0xC000 */
+    HW_CONSTANT_FETCH_MODE_UNIFIED_REG_FILE    = 1,
+}HW_CONSTANT_FETCH_MODE;
+
+typedef enum HW_SAMPLER_FETCH_MODE
+{
+    /* Fetched from non-unified sampler RF */
+    HW_SAMPLER_FETCH_MODE_UNUNIFIED_REG_FILE   = 0,
+
+    /* Fetched from unified constant RF */
+    HW_SAMPLER_FETCH_MODE_UNIFIED_REG_FILE     = 1,
+}HW_SAMPLER_FETCH_MODE;
+
+typedef struct SHADER_HW_PROGRAMMING_HINTS
+{
+    /* Inst fetch mode */
+    gctUINT                                     hwInstFetchMode               : 2;
+
+    /* For HW_INST_FETCH_MODE_UNIFIED_BUFFER_0 and HW_INST_FETCH_MODE_UNIFIED_BUFFER_1
+       it can be non-zero; for HW_INST_FETCH_MODE_UNUNIFIED_BUFFER, must be set to 0 */
+    gctUINT                                     hwInstBufferAddrOffset        : 12;
+
+    /* Constant fetch mode */
+    gctUINT                                     hwConstantFetchMode           : 1;
+
+    /* When constant registers are not allocated as unified, it can be set to no-zero for
+       HW_CONSTANT_FETCH_MODE_UNIFIED_REG_FILE, for other cases, it must be set to 0 */
+    gctUINT                                     hwConstantRegAddrOffset       : 9;
+
+    /* Sampler fetch mode */
+    gctUINT                                     hwSamplerFetchMode            : 1;
+
+    /* When sampler registers are not allocated as unified, it can be set to no-zero for
+       HW_SAMPLER_FETCH_MODE_UNIFIED_REG_FILE, for other cases, it must be set to 0 */
+    gctUINT                                     hwSamplerRegAddrOffset        : 7;
+
+    /* Result-cache is used to queue missed data streamming from up-stage and release them
+       after they are used. This window-size is the size of queue. Note that this result-$
+       occupies some space of USC storage (uscSizeInKbyte). The ocuppied space is calc'ed
+       by (resultCacheWindowSize * outputSizePerThread) */
+    gctUINT                                     resultCacheWindowSize         : 9;
+
+    /* GS only. Each hw thread-group owns meta data for current TG to save counter/restart/
+       stream-index info. Note that it also occupies space of USC storage (uscSizeInKbyte). */
+    gctUINT                                     gsMetaDataSizePerHwTGInBtye   : 16;
+
+    /* Max really runnable thread count per HW thread-group, it can not be greater than
+       maxHwTGThreadCount, i.e, (maxCoreCount * 4) */
+    gctUINT                                     maxThreadsPerHwTG             : 7;
+
+    /* USC is shared by all shader stages, so we need allocate proper size for each stage
+       to get best perf of pipeline. The relation between these two members are
+       1. minUscSizeInKbyte can not be greater than maxUscSizeInKbyte.
+       2. If the minUscSizeInKbyte is equal to maxUscSizeInKbyte, HW will do static allocation
+          within shader type (client) specified maxUscSizeInKbyte USC for this shader stage.
+       3. If the minUscSizeInKbyte is less than maxUscSizeInKbyte HW will do dynamic allocation
+          on total extra-sizes (each extra size is maxUscSizeInKbyte-minUscSizeInKbyte) for each
+          shader stage by insuring the min USC size requirement, */
+    gctUINT                                     maxUscSizeInKbyte             : 8;
+    gctUINT                                     minUscSizeInKbyte             : 8;
+
+    /* Iteration factor to time 'min parallel shader stage combination' when analyzing USC */
+    gctUINT                                     maxParallelFactor             : 16;
+}SHADER_HW_PROGRAMMING_HINTS;
+
+typedef struct SHADER_HW_INFO
+{
+    SHADER_EXECUTABLE_PROFILE*                  pSEP;
+
+    /* Shader linkage info, can be changed by linker */
+    SHADER_IO_LINKAGE_INFO                      inputLinkageInfo;
+    SHADER_IO_LINKAGE_INFO                      outputLinkageInfo;
+
+    /* Machine code flush hint */
+    SHADER_HW_PROGRAMMING_HINTS                 hwProgrammingHints;
+}SHADER_HW_INFO;
+
+gceSTATUS vscInitializeShaderHWInfo(SHADER_HW_INFO* pShaderHwInfo, SHADER_EXECUTABLE_PROFILE* pSEP);
+gceSTATUS vscFinalizeShaderHWInfo(SHADER_HW_INFO* pShaderHwInfo);
+
+END_EXTERN_C();
+
+#endif /* __gc_vsc_drvi_shader_profile_h_ */
+
+
index 59b230e41eb38ecfc67e79fc3f759e2ec9377060..fe0ad19a01da5a75854e3daa2fe31a7de0dcc405 100644 (file)
@@ -11,7 +11,7 @@
 *****************************************************************************/
 
 
-/*Auto created on 2019-05-13 14:37*/
+/*Auto created on 2019-09-26 14:56*/
 #ifndef _gc_feature_database_h_
 #define _gc_feature_database_h_
 
@@ -53,6 +53,7 @@ typedef struct
     gctUINT32 NNCoreCount_INT8;
     gctUINT32 NNCoreCount_INT16;
     gctUINT32 NNCoreCount_FLOAT16;
+    gctUINT32 NNCoreCount_BFLOAT;
     gctUINT32 NNInputBufferDepth;
     gctUINT32 NNAccumBufferDepth;
     gctUINT32 TPEngine_PwlLUTCount;
@@ -443,6 +444,7 @@ typedef struct
     gctUINT32 SHARE_Z:1;
     gctUINT32 DE_2D_FAST_CLEAR:1;
     gctUINT32 TX_CLEAR_PENDING_FIX:1;
+    gctUINT32 NO_HI1_L2:1;
     gctUINT32 VG_TS_CULLING:1;
     gctUINT32 VG_FP25:1;
     gctUINT32 VG_AYUV_INPUT_OUTPUT:1;
@@ -536,6 +538,7 @@ typedef struct
     gctUINT32 NN_WRITE_WITHOUT_USC:1;
     gctUINT32 NN_ZDP_INIMAGE_SIZE_FIX:1;
     gctUINT32 HI_REORDER_FIX:1;
+    gctUINT32 INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX:1;
     gctUINT32 TP_COEF_COMPRESSION_ENHANCEMENT:1;
     gctUINT32 VIP_DEC400:1;
     gctUINT32 IMAGE_NOT_PACKED_IN_SRAM_FIX:1;
@@ -549,9 +552,22 @@ typedef struct
     gctUINT32 USC_BOTTLENECK_FIX:1;
     gctUINT32 KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX:1;
     gctUINT32 FULLCACHE_KERNEL_INTERLEAVE_FIX:1;
+    gctUINT32 TP_REORDER_LAYER_SUSPEND_FIX:1;
+    gctUINT32 KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX:1;
+    gctUINT32 IMG_POP_PIPELINE_PAUSE_FIX:1;
+    gctUINT32 DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX:1;
+    gctUINT32 OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX:1;
     gctUINT32 NN_PER_CHANNEL_POST_MULTIPLY:1;
     gctUINT32 NN_NO_Z_LOCATION_OFFSET:1;
     gctUINT32 NN_PRELU:1;
+    gctUINT32 OCB_REMAP_PHYSICAL_ADDRESS:1;
+    gctUINT32 NN_SLICE_PADDING_TO_64BYTE_ALIGN:1;
+    gctUINT32 NN_DW_1x1_CONV_MERGE:1;
+    gctUINT32 NN_SLOW_OUTPUT:1;
+    gctUINT32 NO_NARROW_POST_PROCESS_PIPE:1;
+    gctUINT32 TP_NN_PROBE:1;
+    gctUINT32 TP_23BITS_POST_MULTIPLIER:1;
+    gctUINT32 NN_TRANSPOSE:1;
 } gcsFEATURE_DATABASE;
 
 static gcsFEATURE_DATABASE gChipInfo[] = {
@@ -592,6 +608,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -982,6 +999,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -1075,6 +1093,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -1086,11 +1105,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x0, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
     /* vipnano-qi */
     {
@@ -1129,6 +1161,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -1519,6 +1552,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -1612,6 +1646,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -1623,11 +1658,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x0, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
     /* vipnano-qi */
     {
@@ -1666,6 +1714,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -2056,6 +2105,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -2149,6 +2199,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -2160,11 +2211,577 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x0, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
+    },
+    /* vipnano-qi */
+    {
+        0x8000, /* ChipID */
+        0x7131, /* ChipRevision */
+        0x5000009, /* ProductID */
+        0x8000000, /* EcoID */
+        0xa1, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x43f000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x1, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
     /* vippico_v3 */
     {
@@ -2203,6 +2820,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -2593,6 +3211,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -2686,6 +3305,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -2697,11 +3317,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x1, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
 };
 
index 0279ce275a88c6099b7da6931d6cd29afbd6b170..6b98a546c81fa43cae2f57a2fb76f034adcaf02f 100644 (file)
@@ -14,7 +14,6 @@
 #ifndef __gc_hal_h_
 #define __gc_hal_h_
 
-#include "gc_hal_rename.h"
 #include "gc_hal_types.h"
 #include "gc_hal_enum.h"
 #include "gc_hal_base.h"
@@ -50,12 +49,6 @@ extern "C" {
          (n) : gcmALIGN(n, align)                                      \
 )
 
-#define gcmALIGN_CHECK_OVERFLOW(n, align)                              \
-(\
-    (gcmALIGN((n) & ~0ULL, (align) & ~0ULL) ^ gcmALIGN(n, align)) ?    \
-         gcvSTATUS_RESLUT_OVERFLOW : gcvSTATUS_OK                      \
-)
-
 #define gcmALIGN_BASE(n, align) \
 (\
     ((n) & ~((align) - 1)) \
@@ -168,6 +161,7 @@ typedef enum _gceOBJECT_TYPE
     gcvOBJ_VARIABLE             = gcmCC('V','A','R','I'),
     gcvOBJ_VERTEX               = gcmCC('V','R','T','X'),
     gcvOBJ_VIDMEM               = gcmCC('V','M','E','M'),
+    gcvOBJ_VIDMEM_BLOCK         = gcmCC('V','M','B','K'),
     gcvOBJ_VG                   = gcmCC('V','G',' ',' '),
     gcvOBJ_BUFOBJ               = gcmCC('B','U','F','O'),
     gcvOBJ_UNIFORM_BLOCK        = gcmCC('U','B','L','K'),
@@ -373,6 +367,19 @@ gckOS_MapPagesEx(
     IN gceVIDMEM_TYPE Type
     );
 
+/* Map 1M pages. */
+gceSTATUS
+gckOS_Map1MPages(
+    IN gckOS Os,
+    IN gceCORE Core,
+    IN gctPHYS_ADDR Physical,
+    IN gctSIZE_T PageCount,
+    IN gctUINT32 Address,
+    IN gctPOINTER PageTable,
+    IN gctBOOL Writable,
+    IN gceVIDMEM_TYPE Type
+    );
+
 gceSTATUS
 gckOS_UnmapPages(
     IN gckOS Os,
@@ -526,6 +533,20 @@ gckOS_WriteRegisterEx_NoDump(
     IN gctUINT32 Data
     );
 
+#ifdef __QNXNTO__
+static gcmINLINE gceSTATUS
+gckOS_WriteMemory(
+    IN gckOS Os,
+    IN gctPOINTER Address,
+    IN gctUINT32 Data
+    )
+{
+    /* Write memory. */
+    *(gctUINT32 *)Address = Data;
+    return gcvSTATUS_OK;
+}
+
+#else
 /* Write data to a 32-bit memory location. */
 gceSTATUS
 gckOS_WriteMemory(
@@ -533,6 +554,7 @@ gckOS_WriteMemory(
     IN gctPOINTER Address,
     IN gctUINT32 Data
     );
+#endif
 
 /* Map physical memory into the process space. */
 gceSTATUS
@@ -1525,7 +1547,6 @@ gckHEAP_ProfileEnd(
     IN gctCONST_STRING Title
     );
 
-
 typedef struct _gckVIDMEM *         gckVIDMEM;
 typedef struct _gckKERNEL *         gckKERNEL;
 typedef struct _gckDB *             gckDB;
@@ -1929,21 +1950,21 @@ gckHARDWARE_ReadInterrupt(
 
 /* Power management. */
 gceSTATUS
-gckHARDWARE_SetPowerManagementState(
+gckHARDWARE_SetPowerState(
     IN gckHARDWARE Hardware,
     IN gceCHIPPOWERSTATE State
     );
 
 gceSTATUS
-gckHARDWARE_QueryPowerManagementState(
+gckHARDWARE_QueryPowerState(
     IN gckHARDWARE Hardware,
     OUT gceCHIPPOWERSTATE* State
     );
 
 gceSTATUS
-gckHARDWARE_SetPowerManagement(
+gckHARDWARE_EnablePowerManagement(
     IN gckHARDWARE Hardware,
-    IN gctBOOL PowerManagement
+    IN gctBOOL Enable
     );
 
 gceSTATUS
@@ -1974,20 +1995,6 @@ gckHARDWARE_SetMinFscaleValue(
     );
 #endif
 
-#if gcdPOWEROFF_TIMEOUT
-gceSTATUS
-gckHARDWARE_SetPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    IN gctUINT32    Timeout
-);
-
-gceSTATUS
-gckHARDWARE_QueryPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    OUT gctUINT32*  Timeout
-);
-#endif
-
 gceSTATUS
 gckHARDWARE_InitializeHardware(
     IN gckHARDWARE Hardware
@@ -2108,6 +2115,7 @@ gceSTATUS
 gckMMU_AllocatePages(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
+    IN gcePAGE_TYPE PageType,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
     );
@@ -2117,6 +2125,7 @@ gckMMU_AllocatePagesEx(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
     IN gceVIDMEM_TYPE Type,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
@@ -2127,6 +2136,7 @@ gceSTATUS
 gckMMU_FreePages(
     IN gckMMU Mmu,
     IN gctBOOL Secure,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctSIZE_T PageCount
@@ -2137,6 +2147,7 @@ gceSTATUS
 gckMMU_SetPage(
    IN gckMMU Mmu,
    IN gctPHYS_ADDR_T PageAddress,
+   IN gcePAGE_TYPE PageType,
    IN gctBOOL Writable,
    IN gctUINT32 *PageEntry
    );
@@ -2150,6 +2161,7 @@ gckMMU_Flush(
 gceSTATUS
 gckMMU_DumpPageTableEntry(
     IN gckMMU Mmu,
+    IN gceAREA_TYPE AreaType,
     IN gctUINT32 Address
     );
 
@@ -2163,10 +2175,17 @@ gckMMU_FillFlatMapping(
 gceSTATUS
 gckMMU_IsFlatMapped(
     IN gckMMU Mmu,
-    OUT gctUINT64 Physical,
+    IN gctUINT64 Physical,
+    IN gctUINT32 Address,
     OUT gctBOOL *In
     );
 
+gceSTATUS
+gckMMU_GetAreaType(
+    IN gckMMU Mmu,
+    IN gctUINT32 GpuAddress,
+    OUT gceAREA_TYPE *AreaType
+    );
 
 gceSTATUS
 gckHARDWARE_QueryContextProfile(
index 0f1ee3744596f57c6433d2e299cb003a932d26c9..f40c9d7f8cd418bde6f0e0f64506f6491a27c95e 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "gc_hal_enum.h"
 #include "gc_hal_types.h"
+#include "gc_hal_debug_zones.h"
 
 
 #ifdef __cplusplus
@@ -47,6 +48,7 @@ typedef struct _gcsBOUNDARY *           gcsBOUNDARY_PTR;
 typedef struct _gcoHARDWARE *           gcoHARDWARE;
 typedef union  _gcuVIDMEM_NODE *        gcuVIDMEM_NODE_PTR;
 typedef struct _gcsVIDMEM_NODE *        gckVIDMEM_NODE;
+typedef struct _gcsVIDMEM_BLOCK *       gckVIDMEM_BLOCK;
 
 typedef void *                          gcoVG;
 
@@ -71,6 +73,7 @@ typedef struct _gcsNN_FIXED_FEATURE
     gctUINT  nnCoreCountInt8;       /* total nn core count supporting int8 */
     gctUINT  nnCoreCountInt16;      /* total nn core count supporting int16 */
     gctUINT  nnCoreCountFloat16;    /* total nn core count supporting float16 */
+    gctUINT  nnCoreCountBFloat16;    /* total nn core count supporting Bfloat16 */
     gctUINT  nnMadPerCore;
     gctUINT  nnInputBufferDepth;
     gctUINT  nnAccumBufferDepth;
@@ -147,7 +150,10 @@ typedef struct _gcsNN_UNIFIED_FEATURE
     gctUINT  axiSramOnlySWTiling : 1;
     gctUINT  imageNotPackedInSram : 1;
     gctUINT  coefDeltaCordOverFlowZRL8BitFix : 1;
+    gctUINT  lowEfficiencyOfIDWriteImgBufFix : 1;
     gctUINT  xyOffsetLimitationFix : 1;
+    gctUINT  kernelPerCoreLTOneThirdCoefFix : 1;
+    gctUINT  diffConditionForCachelineModePreFix : 1;
 } gcsNN_UNIFIED_FEATURE;
 
 /* Features are derived from above ones */
@@ -324,6 +330,8 @@ typedef enum _gcePOOL
     gcvPOOL_SRAM,
     gcvPOOL_VIRTUAL,
     gcvPOOL_USER,
+    gcvPOOL_INTERNAL_SRAM,
+    gcvPOOL_EXTERNAL_SRAM,
 
     gcvPOOL_NUMBER_OF_POOLS
 }
@@ -454,6 +462,20 @@ typedef struct _gcsHAL_LIMITS
 
 }gcsHAL_LIMITS;
 
+
+typedef struct _gcsHAL_CHIPIDENTITY
+{
+    gceCHIPMODEL                chipModel;
+    gctUINT32                   chipRevision;
+    gctUINT32                   productID;
+    gctUINT32                   customerID;
+    gctUINT32                   ecoID;
+    gceCHIP_FLAG                chipFlags;
+    gctUINT64                   platformFlagBits;
+}
+gcsHAL_CHIPIDENTITY;
+
+
 #define gcdEXTERNAL_MEMORY_NAME_MAX 32
 #define gcdEXTERNAL_MEMORY_DATA_MAX 8
 
@@ -618,6 +640,12 @@ gcoHAL_QueryChipIdentity(
     OUT gctUINT32* ChipMinorFeatures
     );
 
+gceSTATUS gcoHAL_QueryChipIdentityEx(
+    IN gcoHAL Hal,
+    IN gctUINT32 SizeOfParam,
+    OUT gcsHAL_CHIPIDENTITY *ChipIdentity
+    );
+
 
 gceSTATUS
 gcoHAL_QuerySuperTileMode(
@@ -639,9 +667,12 @@ gcoHAL_QueryMultiGPUAffinityConfig(
 gceSTATUS
 gcoHAL_QuerySRAM(
     IN gcoHAL Hal,
-    IN gceSRAM Type,
-    OUT gctUINT32 *Base,
-    OUT gctUINT32 *Size
+    IN gcePOOL Type,
+    OUT gctUINT32 *Size,
+    OUT gctUINT32 *GPUVirtAddr,
+    OUT gctPHYS_ADDR_T *GPUPhysAddr,
+    OUT gctUINT32 *GPUPhysName,
+    OUT gctPHYS_ADDR_T *CPUPhysAddr
     );
 
 #ifdef LINUX
@@ -851,7 +882,8 @@ gcoHAL_QueryCluster(
     IN gcoHAL       Hal,
     OUT gctINT32   *ClusterMinID,
     OUT gctINT32   *ClusterMaxID,
-    OUT gctUINT32  *ClusterCount
+    OUT gctUINT32  *ClusterCount,
+    OUT gctUINT32  *ClusterIDWidth
     );
 
 gceSTATUS
@@ -1055,6 +1087,14 @@ gcoHAL_GetGraphicBufferFd(
     OUT gctINT32 * Fd
     );
 
+gceSTATUS
+gcoHAL_AlignToTile(
+    IN OUT gctUINT32 * Width,
+    IN OUT gctUINT32 * Height,
+    IN  gceSURF_TYPE Type,
+    IN  gceSURF_FORMAT Format
+    );
+
 /******************************************************************************\
 ********************************** gcoOS Object *********************************
 \******************************************************************************/
@@ -2295,6 +2335,9 @@ typedef struct _gcsSURF_FORMAT_INFO
     /* sRGB format. */
     gctBOOL                     sRGB;
 
+    /* How GPU read from big-endian host memory */
+    gceENDIAN_HINT              endian;
+
     /* Format components. */
     gcuPIXEL_FORMAT_CLASS       u;
 
@@ -2383,7 +2426,10 @@ gcoSURF_QueryVidMemNode(
     IN gcoSURF Surface,
     OUT gctUINT32 * Node,
     OUT gcePOOL * Pool,
-    OUT gctSIZE_T_PTR Bytes
+    OUT gctSIZE_T_PTR Bytes,
+    OUT gctUINT32 * TsNode,
+    OUT gcePOOL * TsPool,
+    OUT gctSIZE_T_PTR TsBytes
     );
 
 /* Set the color type of the surface. */
@@ -2889,6 +2935,12 @@ gcoSURF_WrapUserMultiBuffer(
     OUT gcoSURF * Surface
     );
 
+gceSTATUS
+gcoSURF_UpdateMetadata(
+    IN gcoSURF Surface,
+    IN gctINT TsFD
+    );
+
 #define MAX_SURF_MIX_SRC_NUM 64
 gceSTATUS
 gcoSURF_MixSurfacesCPU(
@@ -3066,7 +3118,6 @@ gcoHEAP_ProfileEnd(
     );
 #endif
 
-
 /******************************************************************************\
 ******************************* Debugging Macros *******************************
 \******************************************************************************/
@@ -3081,11 +3132,6 @@ gcoOS_GetDebugLevel(
     OUT gctUINT32_PTR DebugLevel
     );
 
-void
-gcoOS_SetDebugZone(
-    IN gctUINT32 Zone
-    );
-
 void
 gcoOS_GetDebugZone(
     IN gctUINT32 Zone,
@@ -3093,17 +3139,10 @@ gcoOS_GetDebugZone(
     );
 
 void
-gcoOS_SetDebugLevelZone(
-    IN gctUINT32 Level,
+gcoOS_SetDebugZone(
     IN gctUINT32 Zone
     );
 
-void
-gcoOS_SetDebugZones(
-    IN gctUINT32 Zones,
-    IN gctBOOL Enable
-    );
-
 void
 gcoOS_SetDebugFile(
     IN gctCONST_STRING FileName
@@ -3230,80 +3269,6 @@ gcoOS_DebugTrace(
 #   define gcmkTRACE_N          __dummy_trace_n
 #endif
 
-/* Zones common for kernel and user. */
-#define gcvZONE_OS              (1 << 0)
-#define gcvZONE_HARDWARE        (1 << 1)
-#define gcvZONE_HEAP            (1 << 2)
-#define gcvZONE_SIGNAL          (1 << 3)
-
-/* Kernel zones. */
-#define gcvZONE_KERNEL          (1 << 4)
-#define gcvZONE_VIDMEM          (1 << 5)
-#define gcvZONE_COMMAND         (1 << 6)
-#define gcvZONE_DRIVER          (1 << 7)
-#define gcvZONE_CMODEL          (1 << 8)
-#define gcvZONE_MMU             (1 << 9)
-#define gcvZONE_EVENT           (1 << 10)
-#define gcvZONE_DEVICE          (1 << 11)
-#define gcvZONE_DATABASE        (1 << 12)
-#define gcvZONE_INTERRUPT       (1 << 13)
-#define gcvZONE_POWER           (1 << 14)
-#define gcvZONE_ASYNC_COMMAND   (1 << 15)
-#define gcvZONE_ALLOCATOR       (1 << 16)
-
-/* User zones. */
-#define gcvZONE_HAL             (1 << 4)
-#define gcvZONE_BUFFER          (1 << 5)
-#define gcvZONE_CONTEXT         (1 << 6)
-#define gcvZONE_SURFACE         (1 << 7)
-#define gcvZONE_INDEX           (1 << 8)
-#define gcvZONE_STREAM          (1 << 9)
-#define gcvZONE_TEXTURE         (1 << 10)
-#define gcvZONE_2D              (1 << 11)
-#define gcvZONE_3D              (1 << 12)
-#define gcvZONE_COMPILER        (1 << 13)
-#define gcvZONE_MEMORY          (1 << 14)
-#define gcvZONE_STATE           (1 << 15)
-#define gcvZONE_AUX             (1 << 16)
-#define gcvZONE_VERTEX          (1 << 17)
-#define gcvZONE_CL              (1 << 18)
-#define gcvZONE_VG              (1 << 19)
-#define gcvZONE_VX              (1 << 20)
-#define gcvZONE_IMAGE           (1 << 21)
-#define gcvZONE_UTILITY         (1 << 22)
-#define gcvZONE_PARAMETERS      (1 << 23)
-#define gcvZONE_BUFOBJ          (1 << 24)
-#define gcvZONE_SHADER          (1 << 25)
-#define gcvZONE_STREAM_OUT      (1 << 26)
-
-/* API definitions. */
-#define gcvZONE_API_HAL         ((gctUINT32) 1  << 28)
-#define gcvZONE_API_EGL         ((gctUINT32) 2  << 28)
-#define gcvZONE_API_ES11        ((gctUINT32) 3  << 28)
-#define gcvZONE_API_ES20        ((gctUINT32) 4  << 28)
-#define gcvZONE_API_ES30        ((gctUINT32) 4  << 28)
-#define gcvZONE_API_VG11        ((gctUINT32) 5  << 28)
-#define gcvZONE_API_GL          ((gctUINT32) 6  << 28)
-#define gcvZONE_API_DFB         ((gctUINT32) 7  << 28)
-#define gcvZONE_API_GDI         ((gctUINT32) 8  << 28)
-#define gcvZONE_API_D3D         ((gctUINT32) 9  << 28)
-#define gcvZONE_API_CL          ((gctUINT32) 10 << 28)
-#define gcvZONE_API_VX          ((gctUINT32) 11 << 28)
-
-
-#define gcmZONE_GET_API(zone)   ((zone) >> 28)
-/*Set gcdZONE_MASE like 0x0 | gcvZONE_API_EGL
-will enable print EGL module debug info*/
-#define gcdZONE_MASK            0x0FFFFFFF
-
-/* Handy zones. */
-#define gcvZONE_NONE            0
-#define gcvZONE_ALL             0x0FFFFFFF
-
-/*Dump API depth set 1 for API, 2 for API and API behavior*/
-#define gcvDUMP_API_DEPTH       1
-
-
 /*******************************************************************************
 **
 **  gcmTRACE_ZONE
@@ -4361,8 +4326,8 @@ gckOS_DebugBreak(
 #   define gcmVERIFY(exp)           gcmASSERT(exp)
 #   define gcmkVERIFY(exp)          gcmkASSERT(exp)
 #else
-#   define gcmVERIFY(exp)           exp
-#   define gcmkVERIFY(exp)          exp
+#   define gcmVERIFY(exp)           (void)exp
+#   define gcmkVERIFY(exp)          (void)exp
 #endif
 
 /*******************************************************************************
@@ -4421,8 +4386,8 @@ gckOS_Verify(
         } \
         while (gcvFALSE)
 #else
-#   define gcmVERIFY_OK(func)       (void)func
-#   define gcmkVERIFY_OK(func)      (void)func
+#   define gcmVERIFY_OK(func)       func
+#   define gcmkVERIFY_OK(func)      func
 #endif
 
 gctCONST_STRING
@@ -4449,7 +4414,7 @@ gckOS_DebugStatus2Name(
 **
 **      func    Function to evaluate.
 */
-#define _gcmERR_BREAK(prefix, func) \
+#define _gcmERR_BREAK(prefix, func){ \
     status = func; \
     if (gcmIS_ERROR(status)) \
     { \
@@ -4459,8 +4424,10 @@ gckOS_DebugStatus2Name(
             status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
         break; \
     } \
-    do { } while (gcvFALSE)
-#define _gcmkERR_BREAK(prefix, func) \
+    do { } while (gcvFALSE); \
+    }
+
+#define _gcmkERR_BREAK(prefix, func){ \
     status = func; \
     if (gcmIS_ERROR(status)) \
     { \
@@ -4470,7 +4437,9 @@ gckOS_DebugStatus2Name(
             status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
         break; \
     } \
-    do { } while (gcvFALSE)
+    do { } while (gcvFALSE); \
+    }
+
 #define gcmERR_BREAK(func)          _gcmERR_BREAK(gcm, func)
 #define gcmkERR_BREAK(func)         _gcmkERR_BREAK(gcmk, func)
 
@@ -4845,14 +4814,6 @@ gckOS_DebugStatus2Name(
 #   define gcmkVERIFY_ARGUMENT_RETURN(arg, value) \
                 _gcmVERIFY_ARGUMENT_RETURN(gcmk, arg, value)
 
-#define _gcmCHECK_ADD_OVERFLOW(x, y) \
-(\
-    ((x) > 0 && (y) > 0 && gcvMAXSIZE_T - (x) < (y)) ? gcvSTATUS_RESLUT_OVERFLOW : gcvSTATUS_OK \
-)
-
-#define gcmCHECK_ADD_OVERFLOW(x, y) _gcmCHECK_ADD_OVERFLOW(x, y)
-#define gcmkCHECK_ADD_OVERFLOW(x, y) _gcmCHECK_ADD_OVERFLOW(x, y)
-
 #define MAX_LOOP_COUNT 0x7FFFFFFF
 
 /******************************************************************************\
@@ -4969,46 +4930,12 @@ gcoHAL_GetUserDebugOption(
 
 #endif
 
-#if gcdSECURE_USER
-
-#   define gcmDEFINESECUREUSER() \
-        gctUINT         __secure_user_offset__; \
-        gctUINT32_PTR   __secure_user_hintArray__;
-
-#   define gcmBEGINSECUREUSER() \
-        __secure_user_offset__ = reserve->lastOffset; \
-        \
-        __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
-
-#   define gcmENDSECUREUSER() \
-        reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
-
-#   define gcmSKIPSECUREUSER() \
-        __secure_user_offset__ += gcmSIZEOF(gctUINT32)
-
-#   define gcmUPDATESECUREUSER() \
-        *__secure_user_hintArray__ = __secure_user_offset__; \
-        \
-        __secure_user_offset__    += gcmSIZEOF(gctUINT32); \
-        __secure_user_hintArray__ += 1
-
-#else
-
-#   define gcmDEFINESECUREUSER()
-#   define gcmBEGINSECUREUSER()
-#   define gcmENDSECUREUSER()
-#   define gcmSKIPSECUREUSER()
-#   define gcmUPDATESECUREUSER()
-
-#endif
-
 /*----------------------------------------------------------------------------*/
 
 /* This style of dump is deprecated. */
 #   define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
 
 #define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
-    gcmDEFINESECUREUSER() \
     gctSIZE_T ReserveSize; \
     gcoCMDBUF CommandBuffer; \
     gctUINT32_PTR Memory; \
@@ -5025,13 +4952,10 @@ gcoHAL_GetUserDebugOption(
     \
     StateDelta = Hardware->delta; \
     \
-    gcmBEGINSECUREUSER(); \
 }
 
 #define gcmENDSTATEBUFFER(Hardware, CommandBuffer, Memory, ReserveSize) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     gcmASSERT(\
         gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
         == \
@@ -5055,8 +4979,6 @@ gcoHAL_GetUserDebugOption(
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmENDSTATEBATCH(CommandBuffer, Memory) \
@@ -5084,8 +5006,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5104,8 +5024,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 
@@ -5120,8 +5038,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETFILLER(CommandBuffer, Memory) \
@@ -5130,8 +5046,6 @@ gcoHAL_GetUserDebugOption(
     \
     *(gctUINT32_PTR)Memory = 0x18000000; \
     Memory += 1; \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*----------------------------------------------------------------------------*/
@@ -5176,8 +5090,6 @@ gcoHAL_GetUserDebugOption(
     gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*******************************************************************************
@@ -5206,7 +5118,6 @@ gcoHAL_GetUserDebugOption(
 ** Temp command buffer macro
 */
 #define gcmDEFINESTATEBUFFER_NEW(CommandBuffer, StateDelta, Memory) \
-    gcmDEFINESECUREUSER() \
     gcmDEFINELOADSTATEBASE() \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
     gctUINT32_PTR Memory; \
@@ -5229,16 +5140,13 @@ gcoHAL_GetUserDebugOption(
         Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
         \
     }\
-    StateDelta = Hardware->delta; \
+    StateDelta = Hardware->tempDelta; \
     \
-    gcmBEGINSECUREUSER(); \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
 }
 
 #define gcmENDSTATEBUFFER_NEW(Hardware, CommandBuffer, Memory, OutSide) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     if (OutSide) \
     {\
         *OutSide = Memory; \
@@ -5249,12 +5157,15 @@ gcoHAL_GetUserDebugOption(
                                          (gctUINT8_PTR)CommandBuffer->buffer); \
         \
         gcmONERROR(gcoBUFFER_EndTEMPCMDBUF(Hardware->engine[CurrentEngine].buffer, gcvFALSE));\
+        if (Hardware->constructType != gcvHARDWARE_2D) \
+        { \
+            gcoHARDWARE_UpdateTempDelta(Hardware);\
+        } \
     }\
     gcmUNSETLOADSTATEBASE()\
 }
 
 #define gcmDEFINECTRLSTATEBUFFER(CommandBuffer, Memory)                         \
-    gcmDEFINESECUREUSER()                                                       \
     gcmDEFINELOADSTATEBASE()                                                    \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL;                                      \
     gctUINT32_PTR Memory;                                                       \
@@ -5275,7 +5186,6 @@ gcoHAL_GetUserDebugOption(
                                                                                 \
         Memory = (gctUINT32_PTR)(CommandBuffer->buffer);                        \
     }                                                                           \
-    gcmBEGINSECUREUSER();                                                       \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);                                 \
 }
 
@@ -5291,8 +5201,6 @@ gcoHAL_GetUserDebugOption(
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmENDSTATEBATCH_NEW(CommandBuffer, Memory) \
@@ -5314,8 +5222,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5332,8 +5238,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 
@@ -5346,16 +5250,12 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETFILLER_NEW(CommandBuffer, Memory) \
 { \
     *(gctUINT32_PTR)Memory = 0x18000000; \
     Memory += 1; \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*----------------------------------------------------------------------------*/
@@ -5400,8 +5300,6 @@ gcoHAL_GetUserDebugOption(
     gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETSTARTDECOMMAND_NEW(CommandBuffer, Memory, Count) \
@@ -5425,8 +5323,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5439,8 +5335,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSINGLESTATE_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5473,8 +5367,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5489,8 +5381,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSINGLESTATE_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5512,13 +5402,11 @@ gcoHAL_GetUserDebugOption(
 }
 
 #define gcmDEFINESTATEBUFFER_NEW_FAST(CommandBuffer, Memory) \
-    gcmDEFINESECUREUSER() \
     gcmDEFINELOADSTATEBASE() \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
     gctUINT32_PTR Memory;
 
 #define gcmDEFINESTATEBUFFER_FAST(CommandBuffer, Memory, ReserveSize) \
-    gcmDEFINESECUREUSER() \
     gctSIZE_T ReserveSize; \
     gcoCMDBUF CommandBuffer; \
     gctUINT32_PTR Memory;
@@ -5531,7 +5419,6 @@ gcoHAL_GetUserDebugOption(
     \
     Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
     \
-    gcmBEGINSECUREUSER(); \
 }
 
 #define gcmBEGINSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
@@ -5550,14 +5437,11 @@ gcoHAL_GetUserDebugOption(
         \
     }\
     \
-    gcmBEGINSECUREUSER(); \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
 }
 
 #define gcmENDSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     if (OutSide) \
     {\
         *OutSide = Memory; \
@@ -5706,6 +5590,97 @@ gcoHAL_GetUserDebugOption(
 }
 #endif
 
+/*******************************************************************************
+**
+**  gcmCONFIGUREUNIFORMS2
+**  only fix clang build error
+**
+**      Configure uniforms according to chip and numConstants.
+*/
+#if !gcdENABLE_UNIFIED_CONSTANT
+#define gcmCONFIGUREUNIFORMS2(ChipModel, ChipRevision, NumConstants, \
+             UnifiedConst, VsConstMax, PsConstMax) \
+{ \
+    if (ChipModel == gcv2000 && (ChipRevision == 0x5118 || ChipRevision == 0x5140)) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 64; \
+    } \
+    else if (NumConstants == 320) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 64; \
+    } \
+    /* All GC1000 series chips can only support 64 uniforms for ps on non-unified const mode. */ \
+    else if (NumConstants > 256 && ChipModel == gcv1000) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 64; \
+    } \
+    else if (NumConstants > 256) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 256; \
+    } \
+    else if (NumConstants == 256) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 256; \
+    } \
+    else \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 168; \
+        PsConstMax   = 64; \
+    } \
+}
+#else
+#define gcmCONFIGUREUNIFORMS2(ChipModel, ChipRevision, Halti5Avail, SmallBatch, NumConstants, \
+             UnifiedConst, VsConstMax, PsConstMax) \
+{ \
+    if (NumConstants > 256) \
+    { \
+        UnifiedConst = gcvTRUE; \
+        if ((ChipModel == gcv880) && ((ChipRevision & 0xfff0) == 0x5120)) \
+        { \
+            VsConstMax   = 512; \
+            PsConstMax   = 64; \
+        } \
+        else \
+        { \
+            VsConstMax   = gcmMIN(512, NumConstants - 64); \
+            PsConstMax   = gcmMIN(512, NumConstants - 64); \
+        } \
+    } \
+    else if (NumConstants == 256) \
+    { \
+        if (ChipModel == gcv2000 && (ChipRevision == 0x5118 || ChipRevision == 0x5140)) \
+        { \
+            UnifiedConst = gcvFALSE; \
+            VsConstMax   = 256; \
+            PsConstMax   = 64; \
+        } \
+        else \
+        { \
+            UnifiedConst = gcvFALSE; \
+            VsConstMax   = 256; \
+            PsConstMax   = 256; \
+        } \
+    } \
+    else \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 168; \
+        PsConstMax   = 64; \
+    } \
+}
+#endif
+
 #define gcmAnyTileStatusEnableForFullMultiSlice(SurfView, anyTsEnableForMultiSlice)\
 {\
     gctUINT i = 0; \
@@ -5811,7 +5786,15 @@ gcoHAL_GetUserDebugOption(
                     prefix##ASSERT(!featureGS); \
                     attribBufSizeInKB = 8; \
                 } \
-                L1cacheSize = featureUSCMaxPages - attribBufSizeInKB; \
+                if (attribBufSizeInKB < featureUSCMaxPages) \
+                { \
+                    L1cacheSize = featureUSCMaxPages - attribBufSizeInKB; \
+                } \
+                else \
+                { \
+                    attribBufSizeInKB -= 2; \
+                    L1cacheSize = 2; \
+                } \
             } \
             prefix##ASSERT(L1cacheSize); \
             if (L1cacheSize >= featureL1CacheSize) \
@@ -5855,6 +5838,88 @@ gcoHAL_GetUserDebugOption(
     } \
 } \
 
+#define gcmCONFIGUSC2(prefix, featureUSC, featureSeparateLS, featureComputeOnly, \
+    featureTS, featureL1CacheSize, featureUSCMaxPages, \
+    attribCacheRatio, L1CacheRatio) \
+{ \
+    attribCacheRatio = 0x2; \
+    \
+    if (featureUSC) \
+    { \
+        if (featureSeparateLS) \
+        { \
+            L1CacheRatio = 0x0; \
+        } \
+        else \
+        { \
+            gctUINT L1cacheSize; \
+            \
+            if (featureComputeOnly) \
+            { \
+                L1cacheSize = featureL1CacheSize; \
+            } \
+            else \
+            { \
+                gctUINT attribBufSizeInKB; \
+                if (featureTS) \
+                { \
+                    /* GS/TS must be bundled. */ \
+                    attribBufSizeInKB = 42; \
+                } \
+                else \
+                { \
+                    attribBufSizeInKB = 8; \
+                } \
+                if (attribBufSizeInKB < featureUSCMaxPages) \
+                { \
+                    L1cacheSize = featureUSCMaxPages - attribBufSizeInKB; \
+                } \
+                else \
+                { \
+                    attribBufSizeInKB -= 4; \
+                    L1cacheSize = 4; \
+                } \
+            } \
+            prefix##ASSERT(L1cacheSize); \
+            if (L1cacheSize >= featureL1CacheSize) \
+            { \
+                L1CacheRatio = 0x0; \
+            } \
+            else \
+            { \
+                static const gctINT s_uscCacheRatio[] = \
+                { \
+                    100000,/* 1.0f */     \
+                    50000, /* 0.5f */     \
+                    25000, /* 0.25f */    \
+                    12500, /* 0.125f */   \
+                    62500, /* 0.0625f */  \
+                    3125, /* 0.03125f */ \
+                    75000, /* 0.75f */    \
+                    0, /*0.0f */      \
+                }; \
+                gctINT maxL1cacheSize = L1cacheSize * 100000; \
+                gctINT delta = 2147483647; /* start with very big delta */ \
+                gctINT i = 0; \
+                gctINT curIndex = -1; \
+                for (; i < gcmCOUNTOF(s_uscCacheRatio); ++i) \
+                { \
+                    gctINT curL1cacheSize = featureL1CacheSize * s_uscCacheRatio[i]; \
+                  \
+                    if ((maxL1cacheSize >= curL1cacheSize) && \
+                        ((maxL1cacheSize - curL1cacheSize) < delta)) \
+                    { \
+                        curIndex = i; \
+                        delta = maxL1cacheSize - curL1cacheSize; \
+                    } \
+                } \
+                prefix##ASSERT(-1 != curIndex); \
+                L1CacheRatio = curIndex; \
+            } \
+        } \
+    } \
+} \
+
 #if VIVANTE_PROFILER_SYSTEM_MEMORY
 typedef struct _memory_profile_info
 {
index 15ce7148d91e4378650e55513fca9321c3da458d..278c55864b27edc728961a227301fb45fc070276 100644 (file)
@@ -726,12 +726,12 @@ gcoCL_SetSignal(
 **
 **  INPUT:
 **
-**      gcsPROGRAM_STATE ProgramState
-**          Program state.
+**      gcsPROGRAM_STATE *ProgramState
+**          Program state pointer.
 */
 gceSTATUS
 gcoCL_LoadKernel(
-    IN gcsPROGRAM_STATE ProgramState
+    IN gcsPROGRAM_STATE *ProgramState
     );
 
 gceSTATUS
@@ -743,7 +743,8 @@ gcoCL_InvokeKernel(
     IN size_t       LocalWorkSize[3],
     IN gctUINT      ValueOrder,
     IN gctBOOL      BarrierUsed,
-    IN gctUINT32    MemoryAccessFlag
+    IN gctUINT32    MemoryAccessFlag,
+    IN gctBOOL      bDual16
     );
 
 gceSTATUS
diff --git a/drivers/amlogic/npu/inc/gc_hal_debug_zones.h b/drivers/amlogic/npu/inc/gc_hal_debug_zones.h
new file mode 100644 (file)
index 0000000..b098c1c
--- /dev/null
@@ -0,0 +1,287 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_debug_zones_h_
+#define __gc_hal_debug_zones_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+ ************************ Debug Zone Pattern Summary ***************************
+ * A debug zone is an unsigned integer of 32 bit (Bit 31- Bit 0).              *
+ * Bit 31 to 28 defines API, which is 0 for HAL API and has value of 1 - 14    *
+ * for Khronos API. Value 15 (0xF) is reserved for gcdZONE_NONE.               *
+ * Bit 27 to 0 defines subzones of each API. Value 0xFFFFFFF is resevered for  *
+ * gcdZONE_ALL.                                                                *
+ *                                                                             *
+\******************************************************************************/
+
+/* Retrieve API bits 31 to 28 */
+#define gcmZONE_GET_API(zone)             ((zone) >> 28)
+
+/* Retrieve Subzone bits 27 to 0 */
+#define gcmZONE_GET_SUBZONES(zone)        ((zone) << 4)
+
+/******************************************************************************\
+******************************** HAL Zone **************************************
+\******************************************************************************/
+
+#define gcdZONE_API_HAL              ((gctUINT32) 0  << 28)
+
+/******************************************************************************\
+******************************** HAL Subzones **********************************
+\******************************************************************************/
+
+/* Subzones Kernel and User have in common */
+#define gcvZONE_OS              (1 << 0)
+#define gcvZONE_HARDWARE        (1 << 1)
+#define gcvZONE_HEAP            (1 << 2)
+#define gcvZONE_SIGNAL          (1 << 3)
+
+/* Subzones of HAL Kernel */
+#define gcvZONE_KERNEL          (1 << 4)
+#define gcvZONE_VIDMEM          (1 << 5)
+#define gcvZONE_COMMAND         (1 << 6)
+#define gcvZONE_DRIVER          (1 << 7)
+#define gcvZONE_CMODEL          (1 << 8)
+#define gcvZONE_MMU             (1 << 9)
+#define gcvZONE_EVENT           (1 << 10)
+#define gcvZONE_DEVICE          (1 << 11)
+#define gcvZONE_DATABASE        (1 << 12)
+#define gcvZONE_INTERRUPT       (1 << 13)
+#define gcvZONE_POWER           (1 << 14)
+#define gcvZONE_ASYNC_COMMAND   (1 << 15)
+#define gcvZONE_ALLOCATOR       (1 << 16)
+
+/* Subzones of HAL User */
+#define gcdZONE_HAL_API         (1 << 4)
+#define gcdZONE_BUFFER          (1 << 5)
+#define gcdZONE_VGBUFFER        (1 << 6)
+#define gcdZONE_SURFACE         (1 << 7)
+#define gcdZONE_INDEX           (1 << 8)
+#define gcdZONE_STREAM          (1 << 9)
+#define gcdZONE_TEXTURE         (1 << 10)
+#define gcdZONE_2D              (1 << 11)
+#define gcdZONE_3D              (1 << 12)
+#define gcdZONE_COMPILER        (1 << 13)
+#define gcdZONE_MEM             (1 << 14)
+#define gcdZONE_VERTEXARRAY     (1 << 15)
+#define gcdZONE_CL              (1 << 16)
+#define gcdZONE_VG              (1 << 17)
+#define gcdZONE_VX              (1 << 18)
+#define gcdZONE_UTILITY         (1 << 19)
+#define gcdZONE_RECT            (1 << 20)
+#define gcdZONE_BUFOBJ          (1 << 21)
+#define gcdZONE_PROFILER        (1 << 22)
+#define gcdZONE_SHADER          (1 << 23)
+
+
+/******************************************************************************\
+******************************** Khronos API Zones *****************************
+\******************************************************************************/
+
+#define gcdZONE_API_EGL              ((gctUINT32) 1  << 28)
+#define gcdZONE_API_ES11             ((gctUINT32) 2  << 28)
+#define gcdZONE_API_ES30             ((gctUINT32) 3  << 28)
+#define gcdZONE_API_GL40             ((gctUINT32) 4  << 28)
+#define gcdZONE_API_VG3D             ((gctUINT32) 5  << 28)
+#define gcdZONE_API_CL               ((gctUINT32) 6  << 28)
+#define gcdZONE_API_VX               ((gctUINT32) 7  << 28)
+#define gcdZONE_API_VG               ((gctUINT32) 8  << 28)
+
+/******************************************************************************\
+************************* Subzones of Khronos API Zones ************************
+\******************************************************************************/
+
+/* Subzones of EGL API */
+#define gcdZONE_EGL_API              (gcdZONE_API_EGL | (1 << 0))
+#define gcdZONE_EGL_SURFACE          (gcdZONE_API_EGL | (1 << 1))
+#define gcdZONE_EGL_CONTEXT          (gcdZONE_API_EGL | (1 << 2))
+#define gcdZONE_EGL_CONFIG           (gcdZONE_API_EGL | (1 << 3))
+#define gcdZONE_EGL_OS               (gcdZONE_API_EGL | (1 << 4))  /* unused */
+#define gcdZONE_EGL_IMAGE            (gcdZONE_API_EGL | (1 << 5))
+#define gcdZONE_EGL_SWAP             (gcdZONE_API_EGL | (1 << 6))
+#define gcdZONE_EGL_INIT             (gcdZONE_API_EGL | (1 << 7))
+#define gcdZONE_EGL_SYNC             (gcdZONE_API_EGL | (1 << 8))
+#define gcdZONE_EGL_COMPOSE          (gcdZONE_API_EGL | (1 << 9))  /* unused */
+#define gcdZONE_EGL_RENDER_THREAD    (gcdZONE_API_EGL | (1 << 10)) /* unused */
+
+/* Subzones of ES11 API */
+#define gcdZONE_ES11_BUFFER          (gcdZONE_API_ES11 | (1 << 0))
+#define gcdZONE_ES11_CLEAR           (gcdZONE_API_ES11 | (1 << 1))
+#define gcdZONE_ES11_CLIP            (gcdZONE_API_ES11 | (1 << 2))
+#define gcdZONE_ES11_CONTEXT         (gcdZONE_API_ES11 | (1 << 3))
+#define gcdZONE_ES11_DRAW            (gcdZONE_API_ES11 | (1 << 4))
+#define gcdZONE_ES11_ENABLE          (gcdZONE_API_ES11 | (1 << 5))
+#define gcdZONE_ES11_EXTENTION       (gcdZONE_API_ES11 | (1 << 6))
+#define gcdZONE_ES11_FOG             (gcdZONE_API_ES11 | (1 << 7))
+#define gcdZONE_ES11_FRAGMENT        (gcdZONE_API_ES11 | (1 << 8))
+#define gcdZONE_ES11_LIGHT           (gcdZONE_API_ES11 | (1 << 9))
+#define gcdZONE_ES11_MATRIX          (gcdZONE_API_ES11 | (1 << 10))
+#define gcdZONE_ES11_PIXEL           (gcdZONE_API_ES11 | (1 << 11))
+#define gcdZONE_ES11_POLIGON         (gcdZONE_API_ES11 | (1 << 12))
+#define gcdZONE_ES11_LINE            (gcdZONE_API_ES11 | (1 << 13)) /* unused */
+#define gcdZONE_ES11_QUERY           (gcdZONE_API_ES11 | (1 << 14))
+#define gcdZONE_ES11_TEXTURE         (gcdZONE_API_ES11 | (1 << 15))
+#define gcdZONE_ES11_STATES          (gcdZONE_API_ES11 | (1 << 16))
+#define gcdZONE_ES11_STREAM          (gcdZONE_API_ES11 | (1 << 17))
+#define gcdZONE_ES11_VIEWPORT        (gcdZONE_API_ES11 | (1 << 18))
+#define gcdZONE_ES11_SHADER          (gcdZONE_API_ES11 | (1 << 19))
+#define gcdZONE_ES11_HASH            (gcdZONE_API_ES11 | (1 << 20))
+#define gcdZONE_ES11_TRACE           (gcdZONE_API_ES11 | (1 << 21))
+
+/* Subzones of ES30 API */
+#define gcdZONE_ES30_TRACE           (gcdZONE_API_ES30 | (1 << 0))
+#define gcdZONE_ES30_BUFFER          (gcdZONE_API_ES30 | (1 << 1))
+#define gcdZONE_ES30_CLEAR           (gcdZONE_API_ES30 | (1 << 2))
+#define gcdZONE_ES30_CODEC           (gcdZONE_API_ES30 | (1 << 3))
+#define gcdZONE_ES30_CONTEXT         (gcdZONE_API_ES30 | (1 << 4))
+#define gcdZONE_ES30_DEPTH           (gcdZONE_API_ES30 | (1 << 5))
+#define gcdZONE_ES30_DEVICE          (gcdZONE_API_ES30 | (1 << 6))
+#define gcdZONE_ES30_DRAW            (gcdZONE_API_ES30 | (1 << 7))
+#define gcdZONE_ES30_FBO             (gcdZONE_API_ES30 | (1 << 8))
+#define gcdZONE_ES30_PIXEL           (gcdZONE_API_ES30 | (1 << 9))
+#define gcdZONE_ES30_SHADER          (gcdZONE_API_ES30 | (1 << 10))
+#define gcdZONE_ES30_STATE           (gcdZONE_API_ES30 | (1 << 11))
+#define gcdZONE_ES30_TEXTURE         (gcdZONE_API_ES30 | (1 << 12))
+#define gcdZONE_ES30_UTILS           (gcdZONE_API_ES30 | (1 << 13))
+#define gcdZONE_ES30_PROFILER        (gcdZONE_API_ES30 | (1 << 14))
+#define gcdZONE_ES30_CORE            (gcdZONE_API_ES30 | (1 << 15))
+
+/* Subzones of GL40 API */
+#define gcdZONE_GL40_TRACE           (gcdZONE_API_GL40 | (1 << 0))
+#define gcdZONE_GL40_BUFFER          (gcdZONE_API_GL40 | (1 << 1))
+#define gcdZONE_GL40_CLEAR           (gcdZONE_API_GL40 | (1 << 2))  /* unused */
+#define gcdZONE_GL40_CODEC           (gcdZONE_API_GL40 | (1 << 3))
+#define gcdZONE_GL40_CONTEXT         (gcdZONE_API_GL40 | (1 << 4))
+#define gcdZONE_GL40_DEPTH           (gcdZONE_API_GL40 | (1 << 5))
+#define gcdZONE_GL40_DEVICE          (gcdZONE_API_GL40 | (1 << 6))
+#define gcdZONE_GL40_DRAW            (gcdZONE_API_GL40 | (1 << 7))
+#define gcdZONE_GL40_FBO             (gcdZONE_API_GL40 | (1 << 8))
+#define gcdZONE_GL40_PIXEL           (gcdZONE_API_GL40 | (1 << 9))
+#define gcdZONE_GL40_SHADER          (gcdZONE_API_GL40 | (1 << 10))
+#define gcdZONE_GL40_STATE           (gcdZONE_API_GL40 | (1 << 11))
+#define gcdZONE_GL40_TEXTURE         (gcdZONE_API_GL40 | (1 << 12))
+#define gcdZONE_GL40_UTILS           (gcdZONE_API_GL40 | (1 << 13))
+#define gcdZONE_GL40_PROFILER        (gcdZONE_API_GL40 | (1 << 14))
+#define gcdZONE_GL40_CORE            (gcdZONE_API_GL40 | (1 << 15))
+#define gcdZONE_GL40_FIXVERTEX       (gcdZONE_API_GL40 | (1 << 16))
+#define gcdZONE_GL40_FIXFRAG         (gcdZONE_API_GL40 | (1 << 17))
+#define gcdZONE_GL40_HASH            (gcdZONE_API_GL40 | (1 << 18))
+
+/* Subzones of VG3D API  */
+#define gcdZONE_VG3D_CONTEXT           (gcdZONE_API_VG3D | (1 << 0))
+#define gcdZONE_VG3D_DUMP              (gcdZONE_API_VG3D | (1 << 1))
+#define gcdZONE_VG3D_EGL               (gcdZONE_API_VG3D | (1 << 2))
+#define gcdZONE_VG3D_FONT              (gcdZONE_API_VG3D | (1 << 3))
+#define gcdZONE_VG3D_HARDWARE          (gcdZONE_API_VG3D | (1 << 4))
+#define gcdZONE_VG3D_IMAGE             (gcdZONE_API_VG3D | (1 << 5))
+#define gcdZONE_VG3D_MASK              (gcdZONE_API_VG3D | (1 << 6))
+#define gcdZONE_VG3D_MATRIX            (gcdZONE_API_VG3D | (1 << 7))
+#define gcdZONE_VG3D_OBJECT            (gcdZONE_API_VG3D | (1 << 8))
+#define gcdZONE_VG3D_PAINT             (gcdZONE_API_VG3D | (1 << 9))
+#define gcdZONE_VG3D_PATH              (gcdZONE_API_VG3D | (1 << 10))
+#define gcdZONE_VG3D_PROFILER          (gcdZONE_API_VG3D | (1 << 11))
+#define gcdZONE_VG3D_SCANLINE          (gcdZONE_API_VG3D | (1 << 12))
+#define gcdZONE_VG3D_SHADER            (gcdZONE_API_VG3D | (1 << 13))
+#define gcdZONE_VG3D_TESSELLATOR       (gcdZONE_API_VG3D | (1 << 14))
+#define gcdZONE_VG3D_VGU               (gcdZONE_API_VG3D | (1 << 15))
+
+/* Subzones of VG11 API  */
+#define gcdZONE_VG_ARC               (gcdZONE_API_VG | (1 << 0))
+#define gcdZONE_VG_CONTEXT           (gcdZONE_API_VG | (1 << 1))
+#define gcdZONE_VG_DEBUG             (gcdZONE_API_VG | (1 << 2))
+#define gcdZONE_VG_FILTER            (gcdZONE_API_VG | (1 << 3))
+#define gcdZONE_VG_FORMAT            (gcdZONE_API_VG | (1 << 4))
+#define gcdZONE_VG_IMAGE             (gcdZONE_API_VG | (1 << 5))
+#define gcdZONE_VG_MAIN              (gcdZONE_API_VG | (1 << 6))
+#define gcdZONE_VG_MASK              (gcdZONE_API_VG | (1 << 7))
+#define gcdZONE_VG_MATRIX            (gcdZONE_API_VG | (1 << 8))
+#define gcdZONE_VG_MEMORYMGR         (gcdZONE_API_VG | (1 << 9))
+#define gcdZONE_VG_OBJECT            (gcdZONE_API_VG | (1 << 10))
+#define gcdZONE_VG_PAINT             (gcdZONE_API_VG | (1 << 11))
+#define gcdZONE_VG_PATH              (gcdZONE_API_VG | (1 << 12))
+#define gcdZONE_VG_STATE             (gcdZONE_API_VG | (1 << 13))
+#define gcdZONE_VG_STROKE            (gcdZONE_API_VG | (1 << 14))
+#define gcdZONE_VG_TEXT              (gcdZONE_API_VG | (1 << 15))
+#define gcdZONE_VG_VGU               (gcdZONE_API_VG | (1 << 16))
+
+/* Subzones of CL API  */
+#define gcdZONE_CL_COMMAND           (gcdZONE_API_CL | (1 << 0))
+#define gcdZONE_CL_CONTEXT           (gcdZONE_API_CL | (1 << 1))
+#define gcdZONE_CL_DEVICE            (gcdZONE_API_CL | (1 << 2))
+#define gcdZONE_CL_ENQUEUE           (gcdZONE_API_CL | (1 << 3))
+#define gcdZONE_CL_EVENT             (gcdZONE_API_CL | (1 << 4))
+#define gcdZONE_CL_EXT               (gcdZONE_API_CL | (1 << 5))
+#define gcdZONE_CL_GL                (gcdZONE_API_CL | (1 << 6))
+#define gcdZONE_CL_KERNEL            (gcdZONE_API_CL | (1 << 7))
+#define gcdZONE_CL_MEM               (gcdZONE_API_CL | (1 << 8))
+#define gcdZONE_CL_PLATFORM          (gcdZONE_API_CL | (1 << 9))
+#define gcdZONE_CL_PROFILER          (gcdZONE_API_CL | (1 << 10))
+#define gcdZONE_CL_PROGRAM           (gcdZONE_API_CL | (1 << 11))
+#define gcdZONE_CL_SAMPLER           (gcdZONE_API_CL | (1 << 12))
+
+/* Subzones of VX API  */
+#define gcdZONE_VX_ARRAY             (gcdZONE_API_VX | (1 << 0))
+#define gcdZONE_VX_BINARY            (gcdZONE_API_VX | (1 << 1))
+#define gcdZONE_VX_CONTEXT           (gcdZONE_API_VX | (1 << 2))
+#define gcdZONE_VX_CONV              (gcdZONE_API_VX | (1 << 3))
+#define gcdZONE_VX_DELAY             (gcdZONE_API_VX | (1 << 4))
+#define gcdZONE_VX_DIST              (gcdZONE_API_VX | (1 << 5))
+#define gcdZONE_VX_GPULAYER          (gcdZONE_API_VX | (1 << 6))
+#define gcdZONE_VX_GRAPH             (gcdZONE_API_VX | (1 << 7))
+#define gcdZONE_VX_IMAGE             (gcdZONE_API_VX | (1 << 8))
+#define gcdZONE_VX_INTERFACE         (gcdZONE_API_VX | (1 << 9))
+#define gcdZONE_VX_KERNEL            (gcdZONE_API_VX | (1 << 10))
+#define gcdZONE_VX_LAYER             (gcdZONE_API_VX | (1 << 11))
+#define gcdZONE_VX_LUT               (gcdZONE_API_VX | (1 << 12))
+#define gcdZONE_VX_MATRIX            (gcdZONE_API_VX | (1 << 13))
+#define gcdZONE_VX_MEMORY            (gcdZONE_API_VX | (1 << 14))
+#define gcdZONE_VX_METAFMT           (gcdZONE_API_VX | (1 << 15))
+#define gcdZONE_VX_NODE              (gcdZONE_API_VX | (1 << 16))
+#define gcdZONE_VX_OBJARRAY          (gcdZONE_API_VX | (1 << 17))
+#define gcdZONE_VX_PARAM             (gcdZONE_API_VX | (1 << 18))
+#define gcdZONE_VX_PROGRAM           (gcdZONE_API_VX | (1 << 19))
+#define gcdZONE_VX_PYRAMID           (gcdZONE_API_VX | (1 << 20))
+#define gcdZONE_VX_REF               (gcdZONE_API_VX | (1 << 21))
+#define gcdZONE_VX_REMAP             (gcdZONE_API_VX | (1 << 22))
+#define gcdZONE_VX_SCALAR            (gcdZONE_API_VX | (1 << 23))
+#define gcdZONE_VX_TARGET            (gcdZONE_API_VX | (1 << 24))
+#define gcdZONE_VX_TENSOR            (gcdZONE_API_VX | (1 << 25))
+#define gcdZONE_VX_THRESHOLD         (gcdZONE_API_VX | (1 << 26))
+#define gcdZONE_VX_OTHERS            (gcdZONE_API_VX | (1 << 27))
+
+/******************************************************************************\
+******************************** Utility Zones *********************************
+\******************************************************************************/
+
+/* Value for Disabling All Subzones */
+#define gcdZONE_NONE                 0xF0000000
+
+/* Value for Enabling All Subzones */
+#define gcdZONE_ALL                  0x0FFFFFFF
+
+
+/******************************************************************************\
+*********************************** END ****************************************
+\******************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_debug_zones_h_ */
+
+
index d58642ca39d2bf504bb9dcec75fccb610b3c4ab9..d39c80b76325112b449384a24b7e7ea9195f0e31 100644 (file)
@@ -92,6 +92,7 @@ typedef enum _gceHAL_COMMAND_CODES
     gcvHAL_READ_PROFILER_REGISTER_SETTING,
     gcvHAL_READ_ALL_PROFILE_REGISTERS_PART1,
     gcvHAL_READ_ALL_PROFILE_REGISTERS_PART2,
+
     /* Query process database info when debug trace and proflie. */
     gcvHAL_DATABASE,
 
@@ -104,7 +105,6 @@ typedef enum _gceHAL_COMMAND_CODES
     /*************** Common end ***************/
 
     /*************** GPU only ***************/
-
     /* Register operations, 2D only. */
     gcvHAL_READ_REGISTER,
     gcvHAL_WRITE_REGISTER,
@@ -116,6 +116,9 @@ typedef enum _gceHAL_COMMAND_CODES
     /* Read frame database, 3D only. */
     gcvHAL_GET_FRAME_INFO,
 
+    /* Set video memory meta data. */
+    gcvHAL_SET_VIDEO_MEMORY_METADATA,
+
     /* Query command buffer, VG only. */
     gcvHAL_QUERY_COMMAND_BUFFER,
 
@@ -136,6 +139,8 @@ typedef enum _gceHAL_COMMAND_CODES
     gcvHAL_NAME_VIDEO_MEMORY,
     gcvHAL_IMPORT_VIDEO_MEMORY,
 
+    /* Mutex Operation. */
+    gcvHAL_DEVICE_MUTEX,
     /*************** GPU only end ***************/
 
     /*************** DEC only ***************/
@@ -159,6 +164,7 @@ typedef enum _gceHAL_COMMAND_CODES
 
     /* Vsimulator only. */
     gcvHAL_UPDATE_DEBUG_CALLBACK,
+    gcvHAL_CONFIG_CTX_FRAMEWORK,
 
     /* Non paged memory management backup compatibility, windows, qnx. */
     gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
@@ -173,7 +179,7 @@ typedef enum _gceHAL_COMMAND_CODES
     gcvHAL_SET_IDLE,
     gcvHAL_RESET,
 
-    /* Command commit done. */
+    /* Command commit done, kernel event only. */
     gcvHAL_COMMIT_DONE,
 
     /* Get video memory file description. */
@@ -272,6 +278,14 @@ typedef struct _gcsHAL_QUERY_VIDEO_MEMORY
 }
 gcsHAL_QUERY_VIDEO_MEMORY;
 
+enum
+{
+    /* GPU can't issue more that 32bit physical address */
+    gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS = 1 << 0,
+
+    gcvPLATFORM_FLAG_IMX_MM           = 1 << 1,
+};
+
 /* gcvHAL_QUERY_CHIP_IDENTITY */
 typedef struct _gcsHAL_QUERY_CHIP_IDENTITY * gcsHAL_QUERY_CHIP_IDENTITY_PTR;
 typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
@@ -347,8 +361,10 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
     gctUINT32                   customerID;
 
     /* CPU view physical address and size of SRAMs. */
-    gctUINT64                   sRAMBases[gcvSRAM_COUNT];
-    gctUINT32                   sRAMSizes[gcvSRAM_COUNT];
+    gctUINT64                   sRAMBases[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMSizes[gcvSRAM_INTER_COUNT];
+
+    gctUINT64                   platformFlagBits;
 }
 gcsHAL_QUERY_CHIP_IDENTITY;
 
@@ -369,15 +385,22 @@ typedef struct _gcsHAL_QUERY_CHIP_OPTIONS
     gctUINT32                   uscAttribCacheRatio;
     gctUINT32                   userClusterMask;
 
-    /* GPU/VIP virtual address of SRAMs. */
-    gctUINT32                   sRAMBaseAddresses[gcvSRAM_COUNT];
-    /* SRAMs size. */
-    gctUINT32                   sRAMSizes[gcvSRAM_COUNT];
-    /* GPU/VIP view physical address of SRAMs. */
-    gctPHYS_ADDR_T              sRAMPhysicalBases[gcvSRAM_COUNT];
+    /* Internal SRAM. */
+    gctUINT32                   sRAMGPUVirtAddrs[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMSizes[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMCount;
 
-    gceSECURE_MODE              secureMode;
+    /* External SRAM. */
+    gctPHYS_ADDR_T              extSRAMCPUPhysAddrs[gcvSRAM_EXT_COUNT];
+    gctPHYS_ADDR_T              extSRAMGPUPhysAddrs[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMGPUVirtAddrs[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMGPUPhysNames[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMSizes[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMCount;
 
+    gceSECURE_MODE              secureMode;
+    gctBOOL                     enableNNTPParallel;
+    gctUINT                     enableSwtilingPhase1;
 }
 gcsHAL_QUERY_CHIP_OPTIONS;
 
@@ -442,6 +465,11 @@ typedef struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
     /* Memory pool to allocate from. */
     IN OUT gctUINT32            pool;
 
+    /* Internal SRAM index. */
+    IN gctINT32                 sRAMIndex;
+    /* External SRAM index. */
+    IN gctINT32                 extSRAMIndex;
+
     /* Allocated video memory. */
     OUT gctUINT32               node;
 }
@@ -724,6 +752,8 @@ typedef struct _gcsHAL_COMMIT
 
     gctBOOL                     shared;
 
+    gctBOOL                     contextSwitched;
+
     /* Commit stamp of this commit. */
     OUT gctUINT64               commitStamp;
 }
@@ -1086,6 +1116,23 @@ typedef struct _gcsHAL_GET_GRAPHIC_BUFFER_FD
 }
 gcsHAL_GET_GRAPHIC_BUFFER_FD;
 
+typedef struct _gcsHAL_VIDEO_MEMORY_METADATA
+{
+    /* Allocated video memory. */
+    IN gctUINT32            node;
+
+    IN gctUINT32            readback;
+
+    INOUT gctINT32          ts_fd;
+    INOUT gctUINT32         fc_enabled;
+    INOUT gctUINT32         fc_value;
+    INOUT gctUINT32         fc_value_upper;
+
+    INOUT gctUINT32         compressed;
+    INOUT gctUINT32         compress_format;
+}
+gcsHAL_VIDEO_MEMORY_METADATA;
+
 /* gcvHAL_GET_VIDEO_MEMORY_FD. */
 typedef struct _gcsHAL_GET_VIDEO_MEMORY_FD
 {
@@ -1110,6 +1157,14 @@ typedef struct _gcsHAL_WAIT_FENCE
 }
 gcsHAL_WAIT_FENCE;
 
+/* gcvHAL_DEVICE_MUTEX: */
+typedef struct _gcsHAL_DEVICE_MUTEX
+{
+    /* Lock or Release device mutex. */
+    gctBOOL                     isMutexLocked;
+}
+gcsHAL_DEVICE_MUTEX;
+
 
 #if gcdDEC_ENABLE_AHB
 /* gcvHAL_DEC300_READ. */
@@ -1177,6 +1232,9 @@ typedef struct _gcsHAL_INTERFACE
     /* Ignore information from TSL when doing IO control */
     gctBOOL                     ignoreTLS;
 
+    /* The mutext already acquired */
+    IN gctBOOL                  commitMutex;
+
     /* Union of command structures. */
     union _u
     {
@@ -1261,12 +1319,16 @@ typedef struct _gcsHAL_INTERFACE
         gcsHAL_WAIT_NATIVE_FENCE            WaitNativeFence;
         gcsHAL_SHBUF                        ShBuf;
         gcsHAL_GET_GRAPHIC_BUFFER_FD        GetGraphicBufferFd;
+        gcsHAL_VIDEO_MEMORY_METADATA        SetVidMemMetadata;
         gcsHAL_GET_VIDEO_MEMORY_FD          GetVideoMemoryFd;
 
         gcsHAL_DESTROY_MMU                  DestroyMmu;
 
         gcsHAL_WAIT_FENCE                   WaitFence;
 
+        /* gcvHAL_DEVICE_MUTEX: */
+        gcsHAL_DEVICE_MUTEX                 DeviceMutex;
+
 
 #if gcdDEC_ENABLE_AHB
         gcsHAL_DEC300_READ                  DEC300Read;
index c6ceefb867d8a0ec9ebefe02d7af73a3cec70521..2d08723ce7e6815dce799960cc121b2e71c24f84 100644 (file)
@@ -82,13 +82,14 @@ typedef struct _gcoBUFOBJ *             gcoBUFOBJ;
 
 typedef enum _gcePROGRAM_STAGE
 {
-    gcvPROGRAM_STAGE_VERTEX   = 0x0,
-    gcvPROGRAM_STAGE_TCS      = 0x1,
-    gcvPROGRAM_STAGE_TES      = 0x2,
-    gcvPROGRAM_STAGE_GEOMETRY = 0x3,
-    gcvPROGRAM_STAGE_FRAGMENT = 0x4,
-    gcvPROGRAM_STAGE_COMPUTE  = 0x5,
-    gcvPROGRAM_STAGE_OPENCL   = 0x6,
+    gcvPROGRAM_STAGE_VERTEX         = 0x0,
+    gcvPROGRAM_STAGE_TCS            = 0x1,
+    gcvPROGRAM_STAGE_TES            = 0x2,
+    gcvPROGRAM_STAGE_GEOMETRY       = 0x3,
+    gcvPROGRAM_STAGE_FRAGMENT       = 0x4,
+    gcvPROGRAM_STAGE_GRAPHICS_COUNT = 0x5,
+    gcvPROGRAM_STAGE_COMPUTE        = 0x5,
+    gcvPROGRAM_STAGE_OPENCL         = 0x6,
     gcvPROGRAM_STAGE_LAST
 }
 gcePROGRAM_STAGE;
@@ -198,6 +199,7 @@ typedef struct _gcsSURF_BLIT_ARGS
     gcsRECT     scissor;
     gctUINT     flags;
     gctUINT     srcNumSlice, dstNumSlice;
+    gctBOOL     needDecode;
 }
 gcsSURF_BLIT_ARGS;
 
@@ -276,6 +278,7 @@ typedef enum _gceSPLIT_DRAW_TYPE
     gcvSPLIT_DRAW_1,
     gcvSPLIT_DRAW_2,
     gcvSPLIT_DRAW_3,
+    gcvSPLIT_DRAW_4,
     gcvSPLIT_DRAW_XFB,
     gcvSPLIT_DRAW_INDEX_FETCH,
     gcvSPLIT_DRAW_TCS,
@@ -635,7 +638,7 @@ gceSTATUS
 gcoINDEX_GetIndexRange(
     IN gcoINDEX Index,
     IN gceINDEX_TYPE Type,
-    IN gctUINT32 Offset,
+    IN gctSIZE_T Offset,
     IN gctUINT32 Count,
     OUT gctUINT32 * MinimumIndex,
     OUT gctUINT32 * MaximumIndex
@@ -1602,6 +1605,7 @@ typedef struct _gcsTHREAD_WALKER_INFO
     gctBOOL     indirect;
     gctUINT32   groupNumberUniformIdx;
     gctUINT32   baseAddress;
+    gctBOOL     bDual16;
 }
 gcsTHREAD_WALKER_INFO;
 
@@ -2146,6 +2150,7 @@ gcoTEXTURE_AddMipMap(
     IN gctSIZE_T Depth,
     IN gctUINT Faces,
     IN gcePOOL Pool,
+    IN gctBOOL Filterable,
     OUT gcoSURF * Surface
     );
 
@@ -2162,6 +2167,7 @@ gcoTEXTURE_AddMipMapEx(
     IN gcePOOL Pool,
     IN gctUINT32 Samples,
     IN gctBOOL Protected,
+    IN gctBOOL Filterable,
     OUT gcoSURF * Surface
     );
 
@@ -2335,7 +2341,8 @@ gceSTATUS
 gcoTEXTURE_GenerateMipMap(
     IN gcoTEXTURE Texture,
     IN gctINT   BaseLevel,
-    IN gctINT   MaxLevel
+    IN gctINT   MaxLevel,
+    IN gctBOOL  sRGBDecode
     );
 
 /******************************************************************************\
@@ -2663,6 +2670,7 @@ typedef struct _gcsVERTEXARRAY_INDEX_INFO
     gctSIZE_T        count;
     gceINDEX_TYPE    indexType;
     gctPOINTER       indexMemory;
+    gctUINT          restartElement;
 
     union _gcsVERTEXARRAY_INDEX_INFO_UNION
     {
@@ -2843,8 +2851,9 @@ gceSTATUS
 gcoBUFOBJ_IndexBind (
     IN gcoBUFOBJ Index,
     IN gceINDEX_TYPE Type,
-    IN gctUINT32 Offset,
-    IN gctSIZE_T Count
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Count,
+    IN gctUINT   RestartElement
     );
 
 /* Find min and max index for the index buffer */
@@ -2852,7 +2861,7 @@ gceSTATUS
 gcoBUFOBJ_IndexGetRange(
     IN gcoBUFOBJ Index,
     IN gceINDEX_TYPE Type,
-    IN gctUINT32 Offset,
+    IN gctSIZE_T Offset,
     IN gctUINT32 Count,
     OUT gctUINT32 * MinimumIndex,
     OUT gctUINT32 * MaximumIndex
index 8ee9adf42ae775ad6eb09a61425a23d58d1d48ed..790b4d47515f808e795644ca31b4b2b773531224 100644 (file)
@@ -57,6 +57,7 @@ typedef enum _gceCHIPMODEL
     gcv6400 = 0x6400,
     gcv7000 = 0x7000,
     gcv7400 = 0x7400,
+    gcv8000 = 0x8000,
 }
 gceCHIPMODEL;
 
@@ -149,7 +150,7 @@ typedef enum _gceFEATURE
     gcvFEATURE_SUPERTILED_TEXTURE,
     gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
     gcvFEATURE_RS_YUV_TARGET,
-    gcvFEATURE_2D_FC_SOURCE,/* For tilestatus compression feature*/
+    gcvFEATURE_2D_FC_SOURCE, /* For tilestatus compression feature*/
     gcvFEATURE_2D_CC_NOAA_SOURCE,
     gcvFEATURE_PE_DITHER_FIX,
     gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
@@ -455,7 +456,6 @@ typedef enum _gceFEATURE
     gcvFEATURE_SH_HALF_DEPENDENCY_FIX,
     gcvFEATURE_FE_BASEINSTANCE,
     gcvFEATURE_FE_COMPUREINDIRECT_SKIP_UNIFORM,
-    gcvFEATURE_FE_DRAW_DIRECT,
     gcvFEATURE_SH_CLOCK_GATE_FIX,
     gcvFEATURE_GPIPE_CLOCK_GATE_FIX,
     gcvFEATURE_TP_ENGINE,
@@ -491,6 +491,7 @@ typedef enum _gceFEATURE
     gcvFEATURE_NN_BRICK_MODE,
     gcvFEATURE_NN_BORDER_MODE,
     gcvFEATURE_NN_FP16_ALU,
+    gcvFEATURE_NN_BF16_ALU,
     gcvFEATURE_NN_INT16_ALU,
     gcvFEATURE_NN_ZDP3,
     gcvFEATURE_NN_ZDP6,
@@ -510,7 +511,6 @@ typedef enum _gceFEATURE
     gcvFEATURE_NN_STRIDE_SUPPORT,
     gcvFEATURE_NN_XYDP6,
     gcvFEATURE_NN_XYDP0,
-    gcvFEATURE_IMAGE_LS_NO_FULLMASK_FIX,
     gcvFEATURE_TP_REORDER_FIX,
     gcvFEATURE_NN_CONV1x1_PERF_FIX,
     gcvFEATURE_NN_CACHELINE_MODE_PERF_FIX,
@@ -525,15 +525,40 @@ typedef enum _gceFEATURE
     gcvFEATURE_NN_ASYNC_COPY_PERF_FIX,
     gcvFEATURE_OCB_COUNTER,
     gcvFEATURE_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX,
+    gcvFEATURE_NN_FULLCACHE_KERNEL_INTERLEAVE_FIX,
+    gcvFEATURE_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX,
+    gcvFEATURE_USC_BOTTLENECK_FIX,
+    gcvFEATURE_OCB_REMAP_PHYSICAL_ADDRESS,
+    gcvFEATURE_NN_SLICE_PADDING_TO_64BYTE_ALIGN,
+    gcvFEATURE_NN_DW_1x1_CONV_MERGE,
+    gcvFEATURE_TP_REORDER_LAYER_SUSPEND_FIX,
+    gcvFEATURE_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX,
+    gcvFEATURE_IMG_POP_PIPELINE_PAUSE_FIX,
+    gcvFEATURE_NN_SLOW_OUTPUT,
+    gcvFEATURE_NO_NARROW_POST_PROCESS_PIPE,
+    gcvFEATURE_TP_NN_PROBE,
+    gcvFEATURE_TP_23BITS_POST_MULTIPLIER,
+    gcvFEATURE_NN_TRANSPOSE,
+
+    gcvFEATURE_IMAGE_LS_NO_FULLMASK_FIX,
+    gcvFEATURE_BLT_YUV_OUTPUT,
+    gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX,
+    gcvFEATURE_SH_ROBUSTNESS_FIX,
     gcvFEATURE_USC_ATOMIC_FIX2,
+    gcvFEATURE_MULTIVIEW_RENDER,
+    gcvFEATURE_FE_DRAW_DIRECT,
+    gcvFEATURE_TX_VKBORDER_MODE,
+    gcvFEATURE_TX_UNNORMALIZED_COORD,
     gcvFEATURE_VG_IMAGE_16K,
     gcvFEATURE_MULTICORE_CONFIG,
+    gcvFEATURE_PA_LINECLIP_FIX,
     gcvFEATURE_NN_ENGINE,
     gcvFEATURE_NN_ASYNC_COPY_MERGE_FIX,
     gcvFEATURE_NN_CONVOUT_FIFO_DEPTH_FIX,
     gcvFEATURE_NN_SMALLBATCH_PHASE1,
     gcvFEATURE_TP_SMALLBATCH_PHASE1,
     gcvFEATURE_VIP_SCALER,
+    gcvFEATURE_TX_8bit_UVFrac_ROUNDING_FIX,
     gcvFEATURE_NN_REQ_SLOWARBITRATION_FIX,
     gcvFEATUER_IMAGE_PARTIAL_CACHE,
     gcvFEATURE_FULLCACHE_KERNELHEAD_FIX,
@@ -550,7 +575,15 @@ typedef enum _gceFEATURE
     gcvFEATURE_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX,
     gcvFEATURE_XY_OFFSET_LIMITATION_FIX,
     gcvFEATURE_USC_INVALIDATE_CACHE_LINE_FIX,
+    gcvFEATURE_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX,
+    gcvFEATURE_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX,
+    gcvFEATURE_NN_PER_CHANNEL_POST_MULTIPLY,
+    gcvFEATURE_NN_NO_Z_LOCATION_OFFSET,
+    gcvFEATURE_NN_PRELU,
+    gcvFEATURE_NN_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX,
+    gcvFEATURE_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX,
     gcvFEATURE_VIP_DEC400,
+    gcvFEATURE_MAX_POINTSIZE_CLAMP,
     gcvFEATURE_2D_FAST_CLEAR, /* For tilestatus Fast Clear feature*/
 
     /* Insert features above this comment only. */
@@ -587,6 +620,7 @@ typedef enum _gceOPTION
     gcvOPTION_FBO_PREFER_MEM = 54,
     gcvOPTION_GPU_TEX_UPLOAD = 55,
     gcvOPTION_GPU_BUFOBJ_UPLOAD = 56,
+    gcvOPTION_NO_Y_INVERT = 60,
 
     /* OCL option */
     gcvOPTION_OCL_ASYNC_BLT = 200,
@@ -601,8 +635,8 @@ typedef enum _gceOPTION
     gcvOPTION_OVX_ENABLE_NN_ZDP6,
     gcvOPTION_OVX_ENABLE_NN_STRIDE,
     gcvOPTION_OVX_USE_MULTI_DEVICES,
+    gcvOPTION_OVX_ENABLE_NN_DDR_BURST_SIZE_256B,
 #endif
-
     /* Insert option above this comment only */
     gcvOPTION_COUNT                     /* Not a OPTION*/
 }
@@ -715,6 +749,7 @@ typedef enum _gceSURF_TYPE
     gcvSURF_NO_HZ                   = 0x100000,
     gcvSURF_3D                      = 0x200000, /* It's 3d surface */
     gcvSURF_DMABUF_EXPORTABLE       = 0x400000, /* master node can be exported as dma-buf fd */
+    gcvSURF_CACHE_MODE_128          = 0x800000,
 
     gcvSURF_TEXTURE_LINEAR               = gcvSURF_TEXTURE
                                          | gcvSURF_LINEAR,
@@ -972,6 +1007,7 @@ typedef enum _gceSURF_FORMAT
     gcvSURF_L16,
     gcvSURF_L32,
     gcvSURF_L1,
+    gcvSURF_L8_RAW,
 
     /* Alpha/Luminance formats. */
     gcvSURF_A4L4                = 900,
@@ -981,6 +1017,10 @@ typedef enum _gceSURF_FORMAT
     gcvSURF_A12L12,
     gcvSURF_A16L16,
 
+    gcvSURF_A8L8_1_A8R8G8B8,
+
+    gcvSURF_A8L8_RAW,
+
     /* Bump formats. */
     gcvSURF_L6V5U5              = 1000,
     gcvSURF_V8U8,
@@ -1629,9 +1669,10 @@ gceFILTER_PASS_TYPE;
 /* Endian hints. */
 typedef enum _gceENDIAN_HINT
 {
-    gcvENDIAN_NO_SWAP = 0,
-    gcvENDIAN_SWAP_WORD,
-    gcvENDIAN_SWAP_DWORD
+    gcvENDIAN_NO_SWAP    = 0,
+    gcvENDIAN_SWAP_WORD  = 1,
+    gcvENDIAN_SWAP_DWORD = 2,
+    gcvENDIAN_SWAP_QWORD = 3,
 }
 gceENDIAN_HINT;
 
@@ -2134,14 +2175,23 @@ typedef enum _gceMCFE_CHANNEL_TYPE
 }
 gceMCFE_CHANNEL_TYPE;
 
-typedef enum _gceSRAM
+typedef enum _gceSRAM_INTERNAL
 {
-    gcvSRAM_INTERNAL  = 0,
-    gcvSRAM_EXTERNAL0 = 1,
-    gcvSRAM_EXTERNAL1 = 2,
-    gcvSRAM_COUNT
+    gcvSRAM_INTERNAL0 = 0,
+    gcvSRAM_INTERNAL1,
+
+    gcvSRAM_INTER_COUNT
 }
-gceSRAM;
+gceSRAM_INTERNAL;
+
+typedef enum _gceSRAM_EXTERNAL
+{
+    gcvSRAM_EXTERNAL0 = 0,
+    gcvSRAM_EXTERNAL1,
+
+    gcvSRAM_EXT_COUNT
+}
+gceSRAM_EXTERNAL;
 
 typedef enum _gceFLATMAP_FLAG
 {
@@ -2150,6 +2200,22 @@ typedef enum _gceFLATMAP_FLAG
 }
 gceFLATMAP_FLAG;
 
+typedef enum _gcePAGE_TYPE
+{
+    gcvPAGE_TYPE_1M,
+    gcvPAGE_TYPE_4K,
+}
+gcePAGE_TYPE;
+
+typedef enum _gceAREA_TYPE
+{
+    gcvAREA_TYPE_UNKNOWN = 0,
+    gcvAREA_TYPE_FLATMAP,
+    gcvAREA_TYPE_1M,
+    gcvAREA_TYPE_4K,
+}
+gceAREA_TYPE;
+
 /* Video memory alloation type. */
 typedef enum _gceVIDMEM_TYPE
 {
@@ -2209,6 +2275,12 @@ gceVIDMEM_TYPE;
 /* Import linux reserved memory. */
 #define gcvALLOC_FLAG_LINUX_RESERVED_MEM    0x00008000
 
+/* 1M pages unit allocation. */
+#define gcvALLOC_FLAG_1M_PAGES              0x00010000
+
+/* Non 1M pages unit allocation. */
+#define gcvALLOC_FLAG_4K_PAGES              0x00020000
+
 /* Real allocation happens when GPU page fault. */
 #define gcvALLOC_FLAG_ALLOC_ON_FAULT        0x01000000
 /* Alloc with memory limit. */
diff --git a/drivers/amlogic/npu/inc/gc_hal_metadata.h b/drivers/amlogic/npu/inc/gc_hal_metadata.h
new file mode 100644 (file)
index 0000000..c12286e
--- /dev/null
@@ -0,0 +1,79 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_metadata_h_
+#define __gc_hal_kernel_metadata_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Macro to combine four characters into a Character Code. */
+#define __FOURCC(a, b, c, d) \
+    ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define VIV_VIDMEM_METADATA_MAGIC __FOURCC('v', 'i', 'v', 'm')
+
+/* Compressed format now was defined same as dec400d, should be general. */
+typedef enum _VIV_COMPRESS_FMT
+{
+    _VIV_CFMT_ARGB8 = 0,
+    _VIV_CFMT_XRGB8,
+    _VIV_CFMT_AYUV,
+    _VIV_CFMT_UYVY,
+    _VIV_CFMT_YUY2,
+    _VIV_CFMT_YUV_ONLY,
+    _VIV_CFMT_UV_MIX,
+    _VIV_CFMT_ARGB4,
+    _VIV_CFMT_XRGB4,
+    _VIV_CFMT_A1R5G5B5,
+    _VIV_CFMT_X1R5G5B5,
+    _VIV_CFMT_R5G6B5,
+    _VIV_CFMT_Z24S8,
+    _VIV_CFMT_Z24,
+    _VIV_CFMT_Z16,
+    _VIV_CFMT_A2R10G10B10,
+    _VIV_CFMT_BAYER,
+    _VIV_CFMT_SIGNED_BAYER,
+    _VIV_CFMT_VAA16,
+    _VIV_CFMT_S8,
+
+    _VIV_CFMT_MAX,
+} _VIV_COMPRESS_FMT;
+
+/* Metadata for cross-device fd share with additional (ts) info. */
+typedef struct _VIV_VIDMEM_METADATA
+{
+    uint32_t magic;
+
+    int32_t  ts_fd;
+    void *   ts_dma_buf;
+#ifdef gcdANDROID
+    dma_addr_t ts_address;
+#endif
+
+    uint32_t fc_enabled;
+    uint32_t fc_value;
+    uint32_t fc_value_upper;
+
+    uint32_t compressed;
+    uint32_t compress_format;
+} _VIV_VIDMEM_METADATA;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_metadata_h_ */
+
+
index ca5de992491f5d5528be135fcbb3ce8c7cf1f628..49cea667a4dcd2c9dc21e0c3b750b60294e236f2 100644 (file)
@@ -372,52 +372,6 @@ This define enables the use of VM for gckCommand and fence buffers.
 #ifndef gcdGC355_VGMMU_MEMORY_SIZE_KB
 #   define gcdGC355_VGMMU_MEMORY_SIZE_KB   32
 #endif
-/*
-    gcdSECURE_USER
-
-        Use logical addresses instead of physical addresses in user land.  In
-        this case a hint table is created for both command buffers and context
-        buffers, and that hint table will be used to patch up those buffers in
-        the kernel when they are ready to submit.
-*/
-#ifndef gcdSECURE_USER
-#   define gcdSECURE_USER                       0
-#endif
-
-/*
-    gcdSECURE_CACHE_SLOTS
-
-        Number of slots in the logical to DMA address cache table.  Each time a
-        logical address needs to be translated into a DMA address for the GPU,
-        this cache will be walked.  The replacement scheme is LRU.
-*/
-#ifndef gcdSECURE_CACHE_SLOTS
-#   define gcdSECURE_CACHE_SLOTS                1024
-#endif
-
-/*
-    gcdSECURE_CACHE_METHOD
-
-        Replacement scheme used for Secure Cache.  The following options are
-        available:
-
-            gcdSECURE_CACHE_LRU
-                A standard LRU cache.
-
-            gcdSECURE_CACHE_LINEAR
-                A linear walker with the idea that an application will always
-                render the scene in a similar way, so the next entry in the
-                cache should be a hit most of the time.
-
-            gcdSECURE_CACHE_HASH
-                A 256-entry hash table.
-
-            gcdSECURE_CACHE_TABLE
-                A simple cache but with potential of a lot of cache replacement.
-*/
-#ifndef gcdSECURE_CACHE_METHOD
-#   define gcdSECURE_CACHE_METHOD               gcdSECURE_CACHE_HASH
-#endif
 
 /*
     gcdREGISTER_READ_FROM_USER
@@ -427,7 +381,7 @@ This define enables the use of VM for gckCommand and fence buffers.
         should only be in debug or development drops.
 */
 #ifndef gcdREGISTER_READ_FROM_USER
-#   define gcdREGISTER_READ_FROM_USER           0
+#   define gcdREGISTER_READ_FROM_USER           1
 #endif
 
 #ifndef gcdREGISTER_WRITE_FROM_USER
@@ -475,7 +429,7 @@ This define enables the use of VM for gckCommand and fence buffers.
 #if gcdFPGA_BUILD
 #   define gcdGPU_TIMEOUT                   2000000
 #else
-#   define gcdGPU_TIMEOUT                   20000
+#   define gcdGPU_TIMEOUT                   40000
 #endif
 #endif
 
@@ -726,6 +680,19 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdRATIO_FOR_SMALL_MEMORY            32
 #endif
 
+/*
+    gcdENABLE_GPU_1M_PAGE
+        When non-zero, GPU page size will be 1M until the pool is out of memory
+        and low-level to 4K pages. When zero, it uses 4k GPU pages.
+*/
+#ifndef gcdENABLE_GPU_1M_PAGE
+#if !gcdSECURITY && defined(LINUX)
+#   define gcdENABLE_GPU_1M_PAGE                1
+#else
+#   define gcdENABLE_GPU_1M_PAGE                0
+#endif
+#endif
+
 /*
     gcdCONTIGUOUS_SIZE_LIMIT
         When non-zero, size of video node from gcvPOOL_VIRTUAL contiguous is
@@ -984,7 +951,7 @@ This define enables the use of VM for gckCommand and fence buffers.
  */
 
 #ifndef gcdINTERRUPT_STATISTIC
-#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDER_CE)
+#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDER_CE) || defined(__VXWORKS__)
 #   define gcdINTERRUPT_STATISTIC               1
 #else
 #   define gcdINTERRUPT_STATISTIC               0
@@ -1326,6 +1293,9 @@ VIV:gcdUSE_MMU_EXCEPTION
 
 #endif
 
+#define gcdHAL_TEST 1
+#define gcdUSE_ZWP_SYNCHRONIZATION 1
+
 /*
     gcdUSE_SINGLE_CONTEXT
         When enabled, will enable single context.
@@ -1334,6 +1304,15 @@ VIV:gcdUSE_MMU_EXCEPTION
 #   define gcdUSE_SINGLE_CONTEXT                   0
 #endif
 
+/*
+    gcdKERNEL_QUERY_PERFORMANCE_COUNTER_V8
+        When enabled, will enable query new performance counter of V8.0 in kernel
+        space.
+ */
+#ifndef gcdKERNEL_QUERY_PERFORMANCE_COUNTER_V8
+#   define gcdKERNEL_QUERY_PERFORMANCE_COUNTER_V8  0
+#endif
+
 #endif /* __gc_hal_options_h_ */
 
 
index dbeff50e45432c851e8c2edb409f52a279d665c2..32a9a86c52f48e3778f1ab871858c4f6250a462a 100644 (file)
@@ -136,6 +136,7 @@ typedef enum _gcePATCH_ID
     gcvPATCH_SILICONSTUDIOGPUMARK,
     gcvPATCH_LEANBACKSCROLLING,
     gcvPATCH_ANTUTU6X, /* Antutu 6.x */
+    gcvPATCH_ANTUTU3DBench,
     gcvPATCH_CAR_CHASE,
     gcvPATCH_ANDROID_BROWSER,
     gcvPATCH_COMPUTBENCH_CL, /* ComputBench 1.5 */
@@ -144,7 +145,13 @@ typedef enum _gcePATCH_ID
     gcvPATCH_GLU4, /* gfx4.0 glu.*/
     gcvPATCH_MRVELBM20,
     gcvPATCH_OPENCV_ATOMIC,
+    gcvPATCH_WESTON,
+    gcvPATCH_SKIA_SKQP,
+    gcvPATCH_SASCHAWILLEMS,
+    gcvPATCH_NATIVEHARDWARE_CTS,
+    gcvPATCH_ANDROID_PHOTOS,
     gcvPATCH_OVX_CTS,
+    gcvPATCH_DEQP_VK,
 
     gcvPATCH_COUNT
 } gcePATCH_ID;
index 08d460caa2b88580ec3dd5832b77b11316cbc7b9..4bd20ec498aa207d6de4d1cc7d0d25d73a7a8d82 100644 (file)
@@ -552,7 +552,9 @@ extern "C" {
 #define VPNC_HIIDLECYCLES                (VPNG_HI + 16)
 #define VPNC_HIREAD8BYTE                 (VPNG_HI + 17)
 #define VPNC_HIWRITE8BYTE                (VPNG_HI + 18)
-#define VPNC_HI_COUNT                    VPNC_HIWRITE8BYTE - VPNG_HI
+#define VPNC_HIOCBREAD16BYTE             (VPNG_HI + 19)
+#define VPNC_HIOCBWRITE16BYTE            (VPNG_HI + 20)
+#define VPNC_HI_COUNT                    VPNC_HIOCBWRITE16BYTE - VPNG_HI
 
 /* HW: L2 Counters. */
 #define VPNC_L2AXI0READREQCOUNT          (VPNG_L2 + 1)
@@ -639,6 +641,12 @@ extern "C" {
 #define DEFAULT_PROFILE_FILE_NAME   "vprofiler.vpd"
 #endif
 
+#define VPHEADER_VERSION "VP20"
+
+#define VPFILETYPE_GL "10"
+
+#define VPFILETYPE_CL "00"
+
 #if gcdENDIAN_BIG
 #define BIG_ENDIAN_TRANS_INT(x) ((gctUINT32)(\
         (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
@@ -722,19 +730,19 @@ extern "C" {
 #define gcmGET_COUNTER(counter, counterId) \
     do \
     { \
-        if ((gctUINT32)*(memory + (counterId + offset) * clusterMaxID) == 0xdeaddead) \
+        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) \
         { \
             counter = 0xdeaddead; \
         } \
         else \
         { \
             gctUINT32 i; \
-            gctUINT64_PTR Memory = memory; \
+            gctUINT32_PTR Memory = memory; \
             counter = 0; \
-            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * clusterMaxID; \
-            for (i = 0; i < (gctUINT32)clusterMaxID; i++) \
+            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * (1 << clusterIDWidth); \
+            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) \
             { \
-                counter += (gctUINT32)*(Memory + (counterId + offset) * clusterMaxID + i); \
+                counter += *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i); \
             } \
         } \
     } \
@@ -743,19 +751,19 @@ extern "C" {
 #define gcmGET_LATENCY_COUNTER(minLatency, maxLatency, counterId) \
     do \
     { \
-        if ((gctUINT32)*(memory + (counterId + offset) * clusterMaxID) == 0xdeaddead) \
+        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) \
         { \
             minLatency = maxLatency = 0xdeaddead; \
         } \
         else \
         { \
             gctUINT32 i; \
-            gctUINT64_PTR Memory = memory; \
-            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * clusterMaxID; \
-            for (i = 0; i < (gctUINT32)clusterMaxID; i++) \
+            gctUINT32_PTR Memory = memory; \
+            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * (1 << clusterIDWidth); \
+            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) \
             { \
-                maxLatency += (((gctUINT32)*(Memory + (counterId + offset) * clusterMaxID + i) & 0xfff000) >> 12); \
-                minLatency += ((gctUINT32)*(Memory + (counterId + offset) * clusterMaxID + i) & 0x000fff); \
+                maxLatency += ((*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0xfff000) >> 12); \
+                minLatency += (*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0x000fff); \
                 if (minLatency == 4095) \
                     minLatency = 0; \
             } \
index 6d30ddcdc2e55dee5fdd911373fbe81e405492a0..d699fb5019db2e05961e287580c456813abd73bf 100644 (file)
@@ -297,6 +297,24 @@ gco2D_SetColorSourceEx(
     IN gctUINT32 TransparencyColor
     );
 
+/* Same as gco2D_SetColorSourceEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetColorSource64(
+    IN gco2D Engine,
+    IN gctUINT32 Address,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Stride,
+    IN gceSURF_FORMAT Format,
+    IN gceSURF_ROTATION Rotation,
+    IN gctUINT32 SurfaceWidth,
+    IN gctUINT32 SurfaceHeight,
+    IN gctBOOL CoordRelative,
+    IN gceSURF_TRANSPARENCY Transparency,
+    IN gctUINT32 TransparencyColor
+    );
+
 /* Configure color source. */
 gceSTATUS
 gco2D_SetColorSourceAdvanced(
@@ -347,6 +365,23 @@ gco2D_SetMaskedSourceEx(
     IN gctUINT32 SurfaceHeight
     );
 
+/* Same as gco2D_SetMaskedSourceEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetMaskedSource64(
+    IN gco2D Engine,
+    IN gctUINT32 Address,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Stride,
+    IN gceSURF_FORMAT Format,
+    IN gctBOOL CoordRelative,
+    IN gceSURF_MONOPACK MaskPack,
+    IN gceSURF_ROTATION Rotation,
+    IN gctUINT32 SurfaceWidth,
+    IN gctUINT32 SurfaceHeight
+    );
+
 /* Setup the source rectangle. */
 gceSTATUS
 gco2D_SetSource(
@@ -382,6 +417,20 @@ gco2D_SetTargetEx(
     IN gctUINT32 SurfaceHeight
     );
 
+/* Same as gco2D_SetTargetEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetTarget64(
+    IN gco2D Engine,
+    IN gctUINT32 Address,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Stride,
+    IN gceSURF_ROTATION Rotation,
+    IN gctUINT32 SurfaceWidth,
+    IN gctUINT32 SurfaceHeight
+    );
+
 /* Calculate and program the stretch factors. */
 gceSTATUS
 gco2D_CalcStretchFactor(
index 047d06ffca05888d80e149a00c809ad742c40a6a..e53c0edd00ae3a2c439b350dc607365057bf8653 100644 (file)
 #   include "linux/types.h"
 #elif defined(UNDER_CE)
 #include <crtdefs.h>
+typedef signed char        int8_t;
+typedef short              int16_t;
+typedef int                int32_t;
+typedef long long          int64_t;
+typedef unsigned char      uint8_t;
+typedef unsigned short     uint16_t;
+typedef unsigned int       uint32_t;
+typedef unsigned long long uint64_t;
 #elif defined(_MSC_VER) && (_MSC_VER <= 1500)
 #include <crtdefs.h>
 #include "vadefs.h"
@@ -94,6 +102,7 @@ extern "C" {
 #   error "gcmINLINE: Platform could not be determined"
 #endif
 
+
 /* Possible debug flags. */
 #define gcdDEBUG_NONE           0
 #define gcdDEBUG_ALL            (1 << 0)
@@ -221,6 +230,8 @@ typedef void *                  gctPOINTER;
 typedef const void *            gctCONST_POINTER;
 
 typedef char                    gctCHAR;
+typedef signed char             gctSIGNED_CHAR;
+typedef unsigned char           gctUNSIGNED_CHAR;
 typedef char *                  gctSTRING;
 typedef const char *            gctCONST_STRING;
 
@@ -443,7 +454,6 @@ typedef enum _gceSTATUS
     gcvSTATUS_DEVICE                =   -27,
     gcvSTATUS_NOT_MULTI_PIPE_ALIGNED =   -28,
     gcvSTATUS_OUT_OF_SAMPLER         =   -29,
-    gcvSTATUS_RESLUT_OVERFLOW       =   -30,
 
     /* Linker errors. */
     gcvSTATUS_GLOBAL_TYPE_MISMATCH              =   -1000,
@@ -819,7 +829,8 @@ gceSTATUS;
 **
 **      Return a value with all bytes in the 32 bit argument swapped.
 */
-#if defined(__GNUC__) && !defined(__KERNEL__)
+#if !defined(__KERNEL__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ >= 40300) \
+   && !defined(__VXWORKS__)
 #  define gcmBSWAP32(x)     __builtin_bswap32(x)
 #else
 #  define gcmBSWAP32(x) ((gctUINT32)(\
@@ -956,8 +967,9 @@ typedef enum _gceTRACEMODE
     gcvTRACEMODE_NONE     = 0,
     gcvTRACEMODE_FULL     = 1,
     gcvTRACEMODE_LOGGER   = 2,
-    gcvTRACEMODE_PRE      = 3,
-    gcvTRACEMODE_POST     = 4,
+    gcvTRACEMODE_ALLZONE  = 3,
+    gcvTRACEMODE_PRE      = 4,
+    gcvTRACEMODE_POST     = 5,
 } gceTRACEMODE;
 
 typedef struct _gcsLISTHEAD * gcsLISTHEAD_PTR;
index a36acf6ccfc673bf16d721c5accbd4d50c061b2b..74787b136ce0f7b2fcab912adeda551aee5355e3 100644 (file)
 
 #define gcvVERSION_MAJOR        6
 
-#define gcvVERSION_MINOR        3
+#define gcvVERSION_MINOR        4
 
-#define gcvVERSION_PATCH        3
+#define gcvVERSION_PATCH        0
 
-#define gcvVERSION_BUILD     210826
+#define gcvVERSION_BUILD     229426
 
-#define gcvVERSION_STRING    "6.3.3.4.210826"
+#define gcvVERSION_STRING    "6.4.0.3.229426"
 
 #endif /* __gc_hal_version_h_ */
 
index cce5e29c70d83af9b5290e50e8a05dc17e6d7086..b669a42e5cc24aa84cfd14e17f7ffd28bf06cd40 100644 (file)
@@ -19,7 +19,6 @@ extern "C" {
 #endif
 
 
-#include "gc_hal_rename.h"
 #include "gc_hal_types.h"
 #include "gc_hal_enum.h"
 #include "gc_hal_base.h"
index 618607fd0a3d7d94d1815ec575a3f9f135c30aea..eb50c75d572f8260a76de519b39a0a72e50ab4b4 100644 (file)
@@ -94,6 +94,8 @@ typedef struct _gcsVX_KERNEL_PARAMETERS
 gcsVX_KERNEL_PARAMETERS;
 #endif
 
+#define MAX_GPU_CORE_COUNT 8
+
 /******************************************************************************\
 ****************************** API Declarations *****************************
 \******************************************************************************/
@@ -176,7 +178,7 @@ gcoVX_BindKernel(
 
 gceSTATUS
 gcoVX_LoadKernelShader(
-    IN gcsPROGRAM_STATE ProgramState
+    IN gcsPROGRAM_STATE *ProgramState
     );
 
 gceSTATUS
@@ -189,7 +191,8 @@ gcoVX_InvokeKernelShader(
     IN size_t              LocalWorkSize[3],
     IN gctUINT             ValueOrder,
     IN gctBOOL             BarrierUsed,
-    IN gctUINT32           MemoryAccessFlag
+    IN gctUINT32           MemoryAccessFlag,
+    IN gctBOOL             bDual16
     );
 
 gceSTATUS
@@ -204,7 +207,8 @@ gcoVX_TriggerAccelerator(
     IN gctUINT32              EventId,
     IN gctBOOL                waitEvent,
     IN gctUINT32              gpuId,
-    IN gctBOOL                sync
+    IN gctBOOL                sync,
+    IN gctUINT32              syncEventID
     );
 
 gceSTATUS
@@ -223,8 +227,18 @@ gcoVX_SetNNImage(
 
 gceSTATUS
 gcoVX_QueryDeviceCount(
-    OUT gctUINT32 * DeviceCount,
-    OUT gctUINT32 * GPUCountPerDevice
+    OUT gctUINT32 * DeviceCount
+    );
+
+gceSTATUS
+gcoVX_QueryCoreCount(
+    IN gctUINT32  DeviceID,
+    OUT gctUINT32 *CoreCount
+    );
+
+gceSTATUS
+gcoVX_QueryMultiCore(
+    OUT gctBOOL *IsMultiCore
     );
 
 gceSTATUS
@@ -248,6 +262,7 @@ gcoVX_FlushCache(
     IN gctBOOL      FlushPSSHL1Cache,
     IN gctBOOL      FlushNNL1Cache,
     IN gctBOOL      FlushTPL1Cache,
+    IN gctBOOL      FlushSHL1Cache,
     IN gctBOOL      Stall
     );
 
@@ -255,12 +270,24 @@ gceSTATUS
 gcoVX_AllocateMemoryEx(
     IN OUT gctUINT *        Bytes,
     IN  gceSURF_TYPE        Type,
+    IN  gcePOOL             Pool,
     IN  gctUINT32           alignment,
     OUT gctUINT32 *         Physical,
     OUT gctPOINTER *        Logical,
     OUT gcsSURF_NODE_PTR *  Node
     );
 
+gceSTATUS
+gcoVX_AllocateMemoryExAddAllocflag(
+    IN OUT gctUINT *        Bytes,
+    IN  gceSURF_TYPE        Type,
+    IN  gctUINT32           alignment,
+    IN  gctUINT32           allocflag,
+    OUT gctUINT32 *         Physical,
+    OUT gctPOINTER *        Logical,
+    OUT gctUINT32 * CpuPhysicalAddress,
+    OUT gcsSURF_NODE_PTR *  Node
+    );
 
 gceSTATUS
 gcoVX_FreeMemoryEx(
@@ -277,11 +304,6 @@ gcoVX_GetMemorySize(
 gceSTATUS
 gcoVX_ZeroMemorySize();
 
-gceSTATUS
-gcoVX_GetHWConfigGpuCount(
-    OUT gctUINT32 *count
-    );
-
 gceSTATUS
 gcoVX_SwitchContext(
     IN  gctUINT DeviceID,
@@ -333,7 +355,9 @@ gcoVX_ProgrammYUV2RGBScale(
 
 gceSTATUS
 gcoVX_CreateHW(
-    IN gctUINT32    DeviceId,
+    IN gctUINT32  DeviceID,
+    IN gctUINT32  GpuCountPerDevice,
+    IN gctUINT32  GpuCoreIndexs[],
     OUT gcoHARDWARE * Hardware
     );
 
diff --git a/drivers/amlogic/npu/inc/gc_vsc_precomp.h b/drivers/amlogic/npu/inc/gc_vsc_precomp.h
new file mode 100644 (file)
index 0000000..4722b02
--- /dev/null
@@ -0,0 +1,26 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_vsc_precomp_h_
+#define __gc_vsc_precomp_h_
+
+#ifdef __cplusplus
+#define BEGIN_EXTERN_C() extern "C" {
+#define END_EXTERN_C()   }
+#else
+#define BEGIN_EXTERN_C()
+#define END_EXTERN_C()
+#endif
+
+#endif /* __gc_vsc_precomp_h_ */
+
diff --git a/drivers/amlogic/npu/inc/old_impl/gc_vsc_old_drvi_interface.h b/drivers/amlogic/npu/inc/old_impl/gc_vsc_old_drvi_interface.h
new file mode 100644 (file)
index 0000000..f0e7131
--- /dev/null
@@ -0,0 +1,8604 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+/*
+**    Include file the defines the front- and back-end compilers, as well as the
+**    objects they use.
+*/
+
+#ifndef __gc_vsc_old_drvi_interface_h_
+#define __gc_vsc_old_drvi_interface_h_
+
+#define _SUPPORT_LONG_ULONG_DATA_TYPE  1
+#define _OCL_USE_INTRINSIC_FOR_IMAGE   1
+#define _SUPPORT_NATIVE_IMAGE_READ     1
+
+#include "gc_hal_engine.h"
+#include "old_impl/gc_vsc_old_gcsl.h"
+
+BEGIN_EXTERN_C()
+
+#define GC_INIT_BUILTIN_CONSTANTS_BY_DRIVER 1
+
+#ifndef GC_ENABLE_LOADTIME_OPT
+#if !DX_SHADER
+#define GC_ENABLE_LOADTIME_OPT      1
+#endif
+#endif
+
+#define TEMP_SHADER_PATCH            1
+
+#ifndef GC_ENABLE_DUAL_FP16
+#define GC_ENABLE_DUAL_FP16          1
+#endif
+
+
+#define GC_ICACHE_PREFETCH_TABLE_SIZE   8
+#define GC_DEFAULT_INLINE_LEVEL         2
+#define GC_DEFAULT_TESS_LEVEL           0xFFFF
+
+/* For OES. */
+#define _sldSharedVariableStorageBlockName  "#sh_sharedVar"
+#define _sldWorkGroupIdName                 "#sh_workgroupId"
+#define __INIT_VALUE_FOR_WORK_GROUP_INDEX__ 0x1234
+
+/* For OCL. */
+#define _sldLocalStorageAddressName         "#sh_local_address"
+#define _sldWorkGroupCountName              "#workGroupCount"
+#define _sldWorkGroupIdOffsetName           "#workGroupIdOffset"
+#define _sldGlobalIdOffsetName              "#globalIdOffset"
+
+/* Shared use. */
+#define _sldLocalMemoryAddressName          "#sh_localMemoryAddress"
+
+#define FULL_PROGRAM_BINARY_SIG_1           gcmCC('F', 'U', 'L', 'L')
+#define FULL_PROGRAM_BINARY_SIG_2           gcmCC('P', 'R', 'G', 'M')
+/** Full program binary file header format: -
+       Word 1:  gcmCC('F', 'U', 'L', 'L') Program binary file signature.
+       Word 2:  gcmCC('P', 'R', 'G', 'M') Program binary file signature.
+       Word 3:  kernel count.
+       Word 4:  size of program binary file in bytes excluding this header.
+*/
+#define __FULL_PROGRAM_BINARY_HEADER_SIZE__     (sizeof(gctUINT32) * 4) /* Full program binary file header size in bytes*/
+
+/** Program binary file header format: -
+       Word 1:  gcmCC('P', 'R', 'G', 'M') Program binary file signature
+       Word 2:  ('\od' '\od' '\od' '\od') od = octal digits; program binary file version
+       Word 3:  ('\E' '\S' '\0' '\0') or Language type
+                ('C' 'L' '\0' '\0')
+       Word 4: ('\0' '\0' '\10' '\0') chip model  e.g. gc800
+       Wor5: ('\1' '\3' '\6' '\4') chip version e.g. 4.6.3_rc1
+       Word 6: size of program binary file in bytes excluding this header */
+#define _gcdProgramBinaryHeaderSize   (6 * 4)  /*Program binary file header size in bytes*/
+
+#define __OCL_PRINTF_WRITE_SIG1__               gcmCC('C', 'L', '\0', '\0')
+#define __OCL_PRINTF_WRITE_SIG2__               gcmCC('P', 'R', 'I', 'N')
+
+typedef enum _gceKernelBinaryKind
+{
+    gcvKERNEL_BINARY_NONE               = 0x00,
+    gcvKERNEL_BINARY_CONST_BORDER       = 0x01,
+}gceKernelinaryKind;
+
+/*
+ *   Re-compilation & Dynamic Linker data sturctures
+ */
+
+enum gceRecompileKind
+{
+    gceRK_PATCH_NONE = 0,
+    gceRK_PATCH_TEXLD_FORMAT_CONVERSION,
+    gceRK_PATCH_OUTPUT_FORMAT_CONVERSION,
+    gceRK_PATCH_DEPTH_COMPARISON,
+    gceRK_PATCH_CONSTANT_CONDITION,
+    gceRK_PATCH_CONSTANT_TEXLD,
+    gceRK_PATCH_COLOR_FACTORING,
+    gceRK_PATCH_ALPHA_BLENDING,
+    gceRK_PATCH_DEPTH_BIAS,
+    gceRK_PATCH_NP2TEXTURE,
+    gceRK_PATCH_GLOBAL_WORK_SIZE, /* OCL */
+    gceRK_PATCH_READ_IMAGE, /* OCL */
+    gceRK_PATCH_WRITE_IMAGE, /* OCL */
+    gceRK_PATCH_Y_FLIPPED_TEXTURE,
+    gceRK_PATCH_REMOVE_ASSIGNMENT_FOR_ALPHA,
+    gceRK_PATCH_Y_FLIPPED_SHADER,
+    gceRK_PATCH_SAMPLE_MASK,
+    gceRK_PATCH_SIGNEXTENT,
+    gceRK_PATCH_TCS_INPUT_COUNT_MISMATCH,
+    gceRK_PATCH_CL_LONGULONG, /* OCL */
+    gceRK_PATCH_COLOR_KILL,
+    gceRK_PATCH_ALPHA_BLEND,
+};
+
+typedef enum _gceConvertFunctionKind
+{
+    gceCF_UNKNOWN,
+    gceCF_RGBA32,
+    gceCF_RGBA32I,
+    gceCF_RGBA32UI,
+    gceCF_RGBA16I,
+    gceCF_RGBA16UI,
+    gceCF_RGBA8I,
+    gceCF_RGBA8UI,
+    gceCF_SRGB8_ALPHA8,
+    gceCF_RGB10_A2,
+    gceCF_RGB10_A2UI,
+/* ... */
+}
+gceConvertFunctionKind;
+
+typedef enum _gceTexldFlavor
+{
+    gceTF_NONE,
+    gceTF_TEXLD = gceTF_NONE,
+    gceTF_PROJ,
+    gceTF_PCF,
+    gceTF_PCFPROJ,
+    gceTF_BIAS_TEXLD,
+    gceTF_BIAS_PROJ,
+    gceTF_BIAS_PCF,
+    gceTF_BIAS_PCFPROJ,
+    gceTF_LOD_TEXLD,
+    gceTF_LOD_PROJ,
+    gceTF_LOD_PCF,
+    gceTF_LOD_PCFPROJ,
+    gceTF_GRAD_TEXLD,
+    gceTF_GRAD_PROJ,
+    gceTF_GRAD_PCF,
+    gceTF_GRAD_PCFPROJ,
+    gceTF_GATHER_TEXLD,
+    gceTF_GATHER_PROJ,
+    gceTF_GATHER_PCF,
+    gceTF_GATHER_PCFPROJ,
+    gceTF_FETCH_MS_TEXLD,
+    gceTF_FETCH_MS_PROJ,
+    gceTF_FETCH_MS_PCF,
+    gceTF_FETCH_MS_PCFPROJ,
+    gceTF_COUNT
+}
+gceTexldFlavor;
+
+extern const gctCONST_STRING gcTexldFlavor[gceTF_COUNT];
+
+typedef enum NP2_ADDRESS_MODE
+{
+    NP2_ADDRESS_MODE_CLAMP  = 0,
+    NP2_ADDRESS_MODE_REPEAT = 1,
+    NP2_ADDRESS_MODE_MIRROR = 2
+}
+NP2_ADDRESS_MODE;
+
+typedef enum gcTEXTURE_MODE
+{
+    gcTEXTURE_MODE_NONE,
+    gcTEXTURE_MODE_POINT,
+    gcTEXTURE_MODE_LINEAR,
+    gcTEXTURE_MODE_COUNT
+}
+gcTEXTURE_MODE;
+
+typedef struct _gcNPOT_PATCH_PARAM
+{
+    gctINT               samplerSlot;
+    NP2_ADDRESS_MODE     addressMode[3];
+    gctINT               texDimension;    /* 2 or 3 */
+}
+gcNPOT_PATCH_PARAM, *gcNPOT_PATCH_PARAM_PTR;
+
+typedef struct _gcsInputConversion
+{
+    gctINT                  layers;       /* numberof layers the input format
+                                             represented internally (up to 4) */
+
+    gcTEXTURE_MODE          mipFilter;
+    gcTEXTURE_MODE          magFilter;
+    gcTEXTURE_MODE          minFilter;
+
+    gctFLOAT                LODBias;
+
+    gctINT                  projected;
+    gctINT                  mipLevelMax;
+    gctINT                  mipLevelMin;
+
+    gctINT                  width;
+    gctINT                  height;
+    gctINT                  depth;
+    gctINT                  dimension;
+    gctBOOL                 srgb;
+    gcUNIFORM               orgShaderSampler;
+    gcUNIFORM               samplers[4];
+    gctINT                  arrayIndex;
+    gcsSURF_FORMAT_INFO     samplerInfo;
+    /* Whether recompile do the swizzle? */
+    gctBOOL                 needSwizzle;
+    /* Whether recompile do the format convert? */
+    gctBOOL                 needFormatConvert;
+    /* 1: use depth, 0: use stencil */
+    gctBOOL                 depthStencilMode;
+    gceTEXTURE_SWIZZLE      swizzle[gcvTEXTURE_COMPONENT_NUM];
+
+    gcSHADER_KIND           shaderKind;
+}
+gcsInputConversion;
+
+typedef struct _gcsOutputConversion
+{
+    gctINT                  layers;       /* numberof layers the input format
+                                             represented internally (up to 4) */
+    gcsSURF_FORMAT_INFO     formatInfo;  /* */
+    gctINT                  outputLocation;
+
+    /* private data.
+       It is not used in the VIR recompilation */
+    gcOUTPUT                outputs[4];
+}
+gcsOutputConversion;
+
+typedef struct _gcsDepthComparison
+{
+    gcsSURF_FORMAT_INFO     formatInfo;
+    gcUNIFORM               sampler;
+    gctINT                  arrayIndex;
+    gctUINT                 compMode;
+    gctUINT                 compFunction;
+    gctBOOL                 convertD32F;   /* the texture format is D32F and
+                                              needs to be converted (halti 0) */
+} gcsDepthComparison;
+
+typedef struct _gcsConstantCondition
+{
+    /* */
+    gctUINT   uniformCount;
+    gctUINT * uniformIdx;       /* a list of index of the uniform which is
+                                   used in constant expression */
+    gctUINT   conditionCount;   /* the number of conditions depended on
+                                   the uniforms */
+}
+gcsConstantCondition;
+
+typedef struct _gcsConstantTexld
+{
+    gctUINT   samplerIndex;
+    gctUINT   instId;            /* the instruction id which has the constant
+                                    coordinate */
+    gctFLOAT  value[4];          /* vec4 value of the texld */
+}
+gcsConstantTexld;
+
+typedef struct _gcsPatchOutputValue
+{
+    gctSTRING   outputName;
+    gctUINT     outputFormatConversion;
+}
+gcsPatchOutputValue;
+
+typedef struct _gcsPatchColorFactoring
+{
+    gctINT    outputLocation;    /* location of render target need to patch */
+    gctFLOAT  value[4];          /* vec4 value of the color factor */
+}
+gcsPatchColorFactoring;
+
+typedef struct _gcsPatchAlphaBlending
+{
+    gctINT    outputLocation;    /* location of render target need to patch */
+}
+gcsPatchAlphaBlending;
+
+typedef struct _gcsPatchDepthBias
+{
+    gcUNIFORM depthBiasUniform;  /* uniform holding the value of depth bias */
+}
+gcsPatchDepthBias;
+
+typedef struct _gcsPatchNP2Texture
+{
+    gctINT textureCount;
+    gcNPOT_PATCH_PARAM_PTR np2Texture;
+}
+gcsPatchNP2Texture;
+
+typedef struct _gcsPatchGlobalWorkSize
+{
+    gcUNIFORM  globalWidth;
+    gcUNIFORM  groupWidth;
+    gctBOOL    patchRealGlobalWorkSize;
+}
+gcsPatchGlobalWorkSize;
+
+typedef struct _gcsPatchReadImage
+{
+    gctUINT                 samplerNum;
+    gctUINT                 imageNum;
+    gctUINT                 imageType;
+    gctUINT                 imageDataIndex;
+    gctUINT                 imageSizeIndex;
+    gctUINT                 samplerValue;
+    gctUINT                 channelDataType;
+    gctUINT                 channelOrder;
+}
+gcsPatchReadImage;
+
+typedef struct _gcsPatchWriteImage
+{
+    gctUINT                 samplerNum;
+    gctUINT                 imageDataIndex;
+    gctUINT                 imageSizeIndex;
+    gctUINT                 channelDataType;
+    gctUINT                 channelOrder;
+    gctUINT                 imageType;
+}
+gcsPatchWriteImage;
+
+typedef struct _gcsPatchLongULong
+{
+    gctUINT                 instructionIndex;
+    gctUINT                 channelCount;       /* channel (target enabled) count */
+}
+gcsPatchLongULong;
+
+typedef struct _gcsPatchYFlippedTexture
+{
+    gcUNIFORM yFlippedTexture;  /* uniform need to filp y component. */
+}
+gcsPatchYFlippedTexture;
+
+typedef struct _gcsPatchYFlippedShader
+{
+    gcUNIFORM rtHeight;  /* uniform contains render target height to filp y component. */
+}
+gcsPatchYFlippedShader;
+
+typedef struct _gcsPatchFlippedSamplePosition
+{
+    gctFLOAT  value;  /* change gl_SamplePosition to (value - gl_SamplePosition); */
+}
+gcsPatchFlippedSamplePosition;
+
+typedef struct _gcsPatchRemoveAssignmentForAlphaChannel
+{
+    gctBOOL removeOutputAlpha[gcdMAX_DRAW_BUFFERS]; /* Flag whether this output need this patch.*/
+}
+gcsPatchRemoveAssignmentForAlphaChannel;
+
+typedef struct _gcsPatchSampleMask
+{
+    /* alpha to converage */
+    gctBOOL                 alphaToConverageEnabled;
+    /* sample coverage */
+    gctBOOL                 sampleConverageEnabled;
+    gcUNIFORM               sampleCoverageValue_Invert; /* float32 x: value,
+                                                         *         y: invert */
+    /* sample mask */
+    gctBOOL                 sampleMaskEnabled;
+    gcUNIFORM               sampleMaskValue;     /* UINT type, the fragment coverage is ANDed
+                                                    with coverage value SAMPLE_MASK_VALUE */
+    /* internal data */
+    gctUINT                 _finalSampleMask;
+    gctINT                  _implicitMaskRegIndex;
+}
+gcsPatchSampleMask;
+
+typedef struct _gcsPatchSignExtent
+{
+    gcUNIFORM               uniform;
+    gctUINT16               arrayIndex;
+}
+gcsPatchSignExtent;
+
+typedef struct _gcsPatchTCSInputCountMismatch
+{
+    gctINT                  inputVertexCount;
+}
+gcsPatchTCSInputCountMismatch;
+
+typedef struct _gcsPatchColorKill
+{
+    gctFLOAT                value;
+}
+gcsPatchColorKill;
+
+typedef struct _gcsPatchAlphaBlend
+{
+    gctINT      outputLocation;
+    gcOUTPUT    outputs[4];
+    gcUNIFORM   alphaBlendEquation;
+    gcUNIFORM   alphaBlendFunction;
+    gcUNIFORM   rtWidthHeight;
+    gcUNIFORM   blendConstColor;
+    gcUNIFORM   rtSampler;     /* sampler */
+    gcUNIFORM   yInvert;
+
+}
+gcsPatchAlphaBlend;
+
+typedef struct _gcRecompileDirective * gcPatchDirective_PTR;
+typedef struct _gcRecompileDirective
+{
+    enum gceRecompileKind   kind;
+    union {
+        gcsInputConversion  *     formatConversion;
+        gcsOutputConversion *     outputConversion;
+        gcsConstantCondition *    constCondition;
+        gcsDepthComparison  *     depthComparison;
+        gcsConstantTexld    *     constTexld;
+        gcsPatchColorFactoring *  colorFactoring;
+        gcsPatchAlphaBlending *   alphaBlending;
+        gcsPatchDepthBias *       depthBias;
+        gcsPatchNP2Texture *      np2Texture;
+        gcsPatchGlobalWorkSize *  globalWorkSize;
+        gcsPatchReadImage *       readImage;
+        gcsPatchWriteImage *      writeImage;
+        gcsPatchYFlippedTexture * yFlippedTexture;
+        gcsPatchRemoveAssignmentForAlphaChannel * removeOutputAlpha;
+        gcsPatchYFlippedShader *  yFlippedShader;
+        gcsPatchSampleMask *      sampleMask;
+        gcsPatchSignExtent *      signExtent;
+        gcsPatchTCSInputCountMismatch *  inputMismatch;
+        gcsPatchLongULong   *     longULong;
+        gcsPatchColorKill *       colorKill;
+        gcsPatchAlphaBlend *      alphaBlend;
+    } patchValue;
+    gcPatchDirective_PTR    next;  /* pointer to next patch directive */
+}
+gcPatchDirective;
+
+typedef struct _gcDynamicPatchInfo
+{
+    gctINT                patchDirectiveCount;
+    gcPatchDirective      patchDirective[1];
+}
+gcDynamicPatchInfo;
+
+typedef enum _gcGL_DRIVER_VERSION {
+    gcGL_DRIVER_ES11, /* OpenGL ES 1.1 */
+    gcGL_DRIVER_ES20, /* OpenGL ES 2.0 */
+    gcGL_DRIVER_ES30     /* OpenGL ES 3.0 */
+}
+gcGL_DRIVER_VERSION;
+
+/* gcSHADER objects. */
+
+typedef struct _gcsHINT *               gcsHINT_PTR;
+typedef struct _gcSHADER_PROFILER *     gcSHADER_PROFILER;
+
+typedef struct _gcsPROGRAM_VidMemPatchOffset
+{
+    gctUINT32 instVidMemInStateBuffer[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctUINT32 gprSpillVidMemInStateBuffer[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctUINT32 crSpillVidMemInStateBuffer[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctUINT32 sharedMemVidMemInStateBuffer;
+
+    gctUINT32 instVidMemInStateDelta[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctUINT32 gprSpillVidMemInStateDelta[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctUINT32 crSpillVidMemInStateDelta[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctUINT32 sharedMemVidMemInStateDelta;
+}
+gcsPROGRAM_VidMemPatchOffset;
+
+
+#define     VSC_STATE_DELTA_END                     0xfeeffeef
+#define     VSC_STATE_DELTA_DESC_SIZE_IN_UINT32     3
+/*
+** stateDelta format is as below in uint32 unit.
+**    offset 0: start state address
+**    offset 1: count of states (n)
+**    offset 2 ~ n + 2: n value of states.
+**    offset n + 3: end tag(VSC_STATE_DELTA_END) for sanity check.
+**    offset n + 4: start state address for next batch
+**    ******
+**    ******
+**    offset of last: end tag(VSC_STATE_DELTA_END)
+*/
+
+typedef struct _gcsPROGRAM_STATE
+{
+    /* Shader program state buffer. */
+    gctUINT32                stateBufferSize;
+    gctPOINTER               stateBuffer;
+    gcsHINT_PTR              hints;
+    gcsPROGRAM_VidMemPatchOffset patchOffsetsInDW;
+    gctUINT32                    stateDeltaSize;
+    gctUINT32                    *stateDelta;
+}
+gcsPROGRAM_STATE, *gcsPROGRAM_STATE_PTR;
+
+
+typedef enum _gceUNIFOEM_ALLOC_MODE
+{
+    /* Non unified allocation, all fixed. */
+    gcvUNIFORM_ALLOC_NONE_UNIFIED                               = 0,
+
+    /* Allocated unified but with float base address offset, pack all stages one by one. */
+    gcvUNIFORM_ALLOC_PACK_FLOAT_BASE_OFFSET                     = 1,
+
+    /* Allocated unified but with float base address offset, pack Gpipe one by one and put them in the top, and put PS in the bottom. */
+    gcvUNIFORM_ALLOC_GPIPE_TOP_PS_BOTTOM_FLOAT_BASE_OFFSET      = 2,
+
+    /* Allocated unified but with float base address offset, pack Gpipe one by one and put them in the bottom, and put PS in the top. */
+    gcvUNIFORM_ALLOC_PS_TOP_GPIPE_BOTTOM_FLOAT_BASE_OFFSET      = 3,
+
+    /* Allocated in full scope of unified register file, all stages use the same register for one uniform. */
+    gcvUNIFORM_ALLOC_FULL_UNIFIED                               = 4,
+}gceUNIFOEM_ALLOC_MODE;
+
+typedef struct _gcsPROGRAM_UNIFIED_STATUS
+{
+    gctBOOL                 useIcache;          /* Icache enabled or not */
+
+    gctBOOL                 instruction; /* unified instruction enabled or not */
+    gceUNIFOEM_ALLOC_MODE   constantUnifiedMode;
+    gceUNIFOEM_ALLOC_MODE   samplerUnifiedMode;
+
+    gctINT                  instVSEnd;       /* VS instr end for unified instruction */
+    gctINT                  instPSStart;     /* PS instr start for unified instruction */
+    /* Valid if UnifiedMode is gcvUNIFORM_ALLOC_FLOAT_BASE_OFFSET and unifiedUniform is disabled. */
+    gctINT                  constGPipeEnd;   /* GPipe const end for unified constant */
+    gctINT                  constPSStart;    /* PS const start for unified constant */
+    gctINT                  samplerGPipeStart; /* GPipe sampler start for unified sampler */
+    gctINT                  samplerPSEnd;  /* PS sampler end for unified sampler */
+    /* Valid if chip can support unified uniform. */
+    gctINT                  constCount;      /* The constant reg count for all shader stages. */
+    gctINT                  samplerCount;    /* The sampler reg count for all shader stages. */
+}
+gcsPROGRAM_UNIFIED_STATUS;
+
+#define PROGRAM_UNIFIED_STATUS_Initialize(UnifiedStatus, TotalSamplerCount)     \
+    do {                                                                        \
+        (UnifiedStatus)->useIcache            = gcvFALSE;                       \
+        (UnifiedStatus)->instruction          = gcvFALSE;                       \
+        (UnifiedStatus)->constantUnifiedMode  = gcvUNIFORM_ALLOC_NONE_UNIFIED;  \
+        (UnifiedStatus)->samplerUnifiedMode   = gcvUNIFORM_ALLOC_NONE_UNIFIED;  \
+        (UnifiedStatus)->instVSEnd            = -1;                             \
+        (UnifiedStatus)->instPSStart          = -1;                             \
+        (UnifiedStatus)->constGPipeEnd        = -1;                             \
+        (UnifiedStatus)->constPSStart         = -1;                             \
+        (UnifiedStatus)->samplerGPipeStart    = (TotalSamplerCount);            \
+        (UnifiedStatus)->samplerPSEnd         = 0;                              \
+        (UnifiedStatus)->constCount           = -1;                             \
+        (UnifiedStatus)->samplerCount         = -1;                             \
+    } while(0)
+
+typedef struct _gcSHADER_VID_NODES
+{
+    gctPOINTER  instVidmemNode[gcMAX_SHADERS_IN_LINK_GOURP]; /* SURF Node for instruction buffer for I-Cache. */
+    gctPOINTER  gprSpillVidmemNode[gcMAX_SHADERS_IN_LINK_GOURP]; /* SURF Node for gpr spill memory. */
+    gctPOINTER  crSpillVidmemNode[gcMAX_SHADERS_IN_LINK_GOURP]; /* SURF Node for cr spill memory. */
+    gctPOINTER  sharedMemVidMemNode;
+}gcSHADER_VID_NODES;
+
+typedef enum _gceMEMORY_ACCESS_FLAG
+{
+    gceMA_FLAG_NONE                 = 0x0000,
+    gceMA_FLAG_LOAD                 = 0x0001,
+    gceMA_FLAG_STORE                = 0x0002,
+    gceMA_FLAG_IMG_READ             = 0x0004,
+    gceMA_FLAG_IMG_WRITE            = 0x0008,
+    gceMA_FLAG_ATOMIC               = 0x0010,
+
+    gceMA_FLAG_READ                 = gceMA_FLAG_LOAD       |
+                                      gceMA_FLAG_IMG_READ   |
+                                      gceMA_FLAG_ATOMIC,
+    gceMA_FLAG_WRITE                = gceMA_FLAG_STORE      |
+                                      gceMA_FLAG_IMG_WRITE  |
+                                      gceMA_FLAG_ATOMIC,
+    gceMA_FLAG_BARRIER              = 0x0020,
+    gceMA_FLAG_EVIS_ATOMADD         = 0x0040, /* evis atomadd can operate on 16B data in parallel,
+                                                * we need to tell driver to turn off workgroup packing
+                                                * if it is used so the HW will not merge different
+                                                * workgroup into one which can cause the different
+                                                * address be used for the evis_atom_add */
+/* must sync with SHADER_EDH_MEM_ACCESS_HINT and VIR_MemoryAccessFlag!!! */
+}
+gceMEMORY_ACCESS_FLAG;
+
+typedef enum _gceFLOW_CONTROL_FLAG
+{
+    gceFC_FLAG_NONE                 = 0x0000,
+    gceFC_FLAG_JMP                  = 0x0001,
+    gceFC_FLAG_CALL                 = 0x0002,
+    gceFC_FLAG_KILL                 = 0x0004,
+/* must sync with SHADER_EDH_FLOW_CONTROL_HINT and VIR_FlowControlFlag!!! */
+}
+gceFLOW_CONTROL_FLAG;
+
+typedef enum _gceTEXLD_FLAG
+{
+    gceTEXLD_FLAG_NONE                 = 0x0000,
+    gceTEXLD_FLAG_TEXLD                = 0x0001,
+/* must sync with SHADER_EDH_TEXLD_HINT and VIR_TexldFlag!!! */
+}
+gceTEXLD_FLAG;
+
+typedef enum _gceSHADER_LEVEL
+{
+    gcvSHADER_HIGH_LEVEL            = 0,
+    gcvSHADER_MACHINE_LEVEL         = 1,
+    gcvSHADER_LEVEL_COUNT           = 2,
+}
+gceSHADER_LEVEL;
+
+typedef struct _gcWORK_GROUP_SIZE
+{
+    gctUINT       x;
+    gctUINT       y;
+    gctUINT       z;
+}gcWORK_GROUP_SIZE;
+
+typedef struct _gcsHINT
+{
+    /* fields for the program */
+    gctUINT32   elementCount;       /* Element count. */
+    gctUINT32   componentCount;     /* Component count. */
+    gctUINT     maxInstCount;
+    gctUINT     maxConstCount;      /* Shader uniform registers. */
+
+    gceSHADING  shaderMode;         /* Flag whether program is smooth or flat. */
+    gctUINT32   shaderConfigData;   /* Data for register: 0x0218.
+                                       For vertex shader, only save the bit that
+                                       would be covered on fragment shader.*/
+
+    gctUINT32   balanceMin;         /* Balance minimum. */
+    gctUINT32   balanceMax;         /* Balance maximum. */
+
+    gceMEMORY_ACCESS_FLAG memoryAccessFlags[gcvSHADER_LEVEL_COUNT][gcvPROGRAM_STAGE_LAST]; /* Memory access flag. */
+
+    gceFLOW_CONTROL_FLAG flowControlFlags[gcvSHADER_LEVEL_COUNT][gcvPROGRAM_STAGE_LAST]; /* Flow control flag. */
+
+    gceTEXLD_FLAG texldFlags[gcvSHADER_LEVEL_COUNT][gcvPROGRAM_STAGE_LAST]; /* Texld flag. */
+
+    gcsPROGRAM_UNIFIED_STATUS unifiedStatus;
+
+#if TEMP_SHADER_PATCH
+    gctUINT32   pachedShaderIdentifier;
+#endif
+
+    /* fields for Vertex shader */
+    gctUINT     vertexShaderId;     /* vertex shader id, to help identifying
+                                     * shaders used by draw commands */
+    gctUINT     vsInstCount;
+    gctUINT32   vsOutputCount;      /* Numbr of data transfers for VS output */
+    gctUINT     vsConstCount;
+    gctUINT32   vsMaxTemp;          /* Maximum number of temporary registers used in VS. */
+    gctUINT32   vsLTCUsedUniformStartAddress; /* the start physical address for
+                                                 uniforms only used in LTC expression */
+
+    /* fields for Fragment shader */
+    gctUINT     fragmentShaderId;   /*fragment shader id, to help identifying
+                                     * shaders used by draw commands */
+    gctUINT     fsInstCount;
+    gctUINT32   fsInputCount;       /* Number of data transfers for FS input. */
+    gctUINT     fsConstCount;
+    gctUINT32   fsMaxTemp;          /* Maximum number of temporary registers used in FS. */
+    gctUINT32   fsLTCUsedUniformStartAddress;   /* the start physical address for
+                                                   uniforms only used in LTC expression */
+    gctUINT     psInputControlHighpPosition;
+    gctUINT     psHighPVaryingCount;
+    gctINT32    psOutput2RtIndex[gcdMAX_DRAW_BUFFERS];
+
+#if gcdALPHA_KILL_IN_SHADER
+    /* States to set when alpha kill is enabled. */
+    gctUINT32   killStateAddress;
+    gctUINT32   alphaKillStateValue;
+    gctUINT32   colorKillStateValue;
+
+    /* Shader instructiuon. */
+    gctUINT32   killInstructionAddress;
+    gctUINT32   alphaKillInstruction[3];
+    gctUINT32   colorKillInstruction[3];
+#endif
+
+    /* gctBOOL isdefined as signed int, 1 bit will have problem if the value
+     * is not used to test zero or not, use 2 bits to avoid the potential error
+     */
+    gctBOOL     removeAlphaAssignment : 2; /* Flag whether this program can remove
+                                              alpha assignment*/
+    gctBOOL     autoShift             : 2; /* Auto-shift balancing. */
+    gctBOOL     vsHasPointSize        : 2; /* Flag whether VS has point size or not */
+    gctBOOL     vsPtSizeAtLastLinkLoc : 2; /* Flag point size will be put at the last link loc for VS */
+    gctBOOL     vsUseStoreAttr        : 2;
+    gctBOOL     psHasFragDepthOut     : 2; /* Flag whether the PS outputs the depth value or not. */
+    gctBOOL     hasKill               : 2; /* Flag whether or not the shader has a KILL instruction. */
+    gctBOOL     psHasDiscard          : 2; /* Flag whether the PS code has discard. */
+
+    gctBOOL     threadWalkerInPS      : 2; /* Flag whether the ThreadWalker is in PS. */
+    gctBOOL     fsIsDual16            : 2;
+    gctBOOL     useSamplePosition     : 2;
+    gctBOOL     useFrontFacing        : 2;
+    gctBOOL     useDSX                : 2;
+    gctBOOL     useDSY                : 2;
+    gctBOOL     yInvertAware          : 2;
+    gctBOOL     hasCentroidInput      : 2; /* flag if PS uses any inputs defined as centroid. */
+    gctBOOL     disableEarlyZ         : 2; /* Disable EarlyZ for this program. */
+    gctBOOL     threadGroupSync       : 2;
+    gctBOOL     usedSampleIdOrSamplePosition : 2; /* For sample shading. */
+    gctBOOL     sampleMaskOutWritten  : 2;
+    gctBOOL     psUsedSampleInput     : 2;
+    gctBOOL     prePaShaderHasPointSize : 2;  /* Flag whether pre-PA has point size or not */
+    gctBOOL     isPtSizeStreamedOut   : 2; /* Flag point size will be streamed out */
+    gctBOOL     hasAttrStreamOuted    : 2; /* Flag any attribute that will be streamed out */
+    gctBOOL     prePaShaderHasPrimitiveId : 2;
+    gctBOOL     sharedMemAllocByCompiler : 2; /* Flag whether share memory is allocated by compiler */
+    /* If any reged CTCs are used in the shader. */
+#if gcdUSE_WCLIP_PATCH
+    gctBOOL     vsPositionZDependsOnW  : 2; /* Flag whether the VS gl_position.z
+                                               depends on gl_position.w it's a hint
+                                               for wclipping */
+    gctBOOL     strictWClipMatch      : 2; /* Strict WClip match. */
+    gctBOOL     WChannelEqualToZ      : 2;
+#endif
+    gctBOOL     useGroupId            : 2;
+    gctBOOL     useLocalId            : 2;
+    gctUINT     fragColorUsage        : 2;
+    /* flag if the shader uses gl_FragCoord, gl_FrontFacing, gl_PointCoord */
+    gctCHAR     useFragCoord[4];
+    gctCHAR     usePointCoord[4];
+    gctCHAR     useRtImage[4];
+    gctCHAR     useRegedCTC[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctCHAR     interpolationType[128];
+
+    gctBOOL     useEarlyFragmentTest;    /* flag if PS uses early fragment tests. */
+    gctINT      sampleMaskLoc; /* -1 means loc can be determined by driver */
+
+    /* They're component index after packing */
+    gctINT      pointCoordComponent;
+    gctINT      rtArrayComponent;
+    gctINT      primIdComponent;
+
+#if gcdUSE_WCLIP_PATCH
+    gctINT      MVPCount;
+#endif
+    /* fields for Tessellation control shader */
+    gctUINT     tcsShaderId;        /* Tessellation control shader id, to help
+                                     * identifying shaders used by draw commands */
+
+    /* fields for Tessellation evaluation shader */
+    gctUINT     tesShaderId;        /* Tessellation evaluation shader id, to help
+                                     * identifying shaders used by draw commands */
+
+    /* fields for Geometry shader */
+    gctUINT     gsShaderId;        /* Geometry shader id, to help identifying
+                                     *  shaders used by draw commands */
+
+    /* Instruction prefetch table. */
+    gctINT32    vsICachePrefetch[GC_ICACHE_PREFETCH_TABLE_SIZE];
+    gctINT32    tcsICachePrefetch[GC_ICACHE_PREFETCH_TABLE_SIZE];
+    gctINT32    tesICachePrefetch[GC_ICACHE_PREFETCH_TABLE_SIZE];
+    gctINT32    gsICachePrefetch[GC_ICACHE_PREFETCH_TABLE_SIZE];
+    gctINT32    fsICachePrefetch[GC_ICACHE_PREFETCH_TABLE_SIZE];
+
+    gcePROGRAM_STAGE_BIT  stageBits;
+
+    gctUINT     usedSamplerMask;
+    gctUINT     usedRTMask;
+
+    /* For CL and CS, global/group/local id order. */
+    gctUINT32   valueOrder;
+
+    /* Deferred-program when flushing as they are in VS output ctrl reg */
+    gctINT      vsOutput16RegNo;
+    gctINT      vsOutput17RegNo;
+    gctINT      vsOutput18RegNo;
+
+    gctINT32    shader2PaOutputCount; /* Output count from pre-pa shader (excluding pure TFX count) */
+    gctUINT     ptSzAttrIndex;
+    /* Sampler Base offset. */
+    gctUINT32   samplerBaseOffset[gcvPROGRAM_STAGE_LAST];
+
+    /* const regNo base */
+    gctUINT32   hwConstRegBases[gcvPROGRAM_STAGE_LAST];
+    gctUINT32   constRegNoBase[gcvPROGRAM_STAGE_LAST];
+
+    gctINT      psOutCntl0to3;
+    gctINT      psOutCntl4to7;
+    gctINT      psOutCntl8to11;
+    gctINT      psOutCntl12to15;
+
+    gcWORK_GROUP_SIZE workGrpSize;
+    gctUINT16   workGroupSizeFactor[3];
+
+    /* per-vertex attributeCount. */
+    gctUINT     tcsPerVertexAttributeCount;
+
+    gctUINT     extraUscPages;
+
+    /* Concurrent workThreadCount. */
+    gctUINT16   workThreadCount;
+
+    /* Local/share memory size. */
+    gctUINT     localMemSizeInByte;
+
+    /* Concurrent workGroupCount. */
+    gctUINT16   workGroupCount;
+
+    /* Sampler Base offset. */
+    gctBOOL     useGPRSpill[gcvPROGRAM_STAGE_LAST];
+
+    /* padding bytes to make the offset of shaderVidNodes field be consistent in 32bit and 64bit platforms */
+    gctCHAR     reserved[8];
+
+    /* shaderVidNodes should always be the LAST filed in hits. */
+    /* SURF Node for memory that is used in shader. */
+    gcSHADER_VID_NODES shaderVidNodes;
+
+    /* padding bytes to make the struct size be consistent in 32bit and 64bit platforms */
+    gctCHAR     reserved1[4];
+}gcsHINT;
+
+#define gcsHINT_isCLShader(Hint)            ((Hint)->clShader)
+#define gcsHINT_GetShaderMode(Hint)         ((Hint)->shaderMode)
+#define gcsHINT_GetSurfNode(Hint)           ((Hint)->surfNode)
+
+#define gcsHINT_SetProgramStageBit(Hint, Stage) do { (Hint)->stageBits |= 1 << Stage;} while (0)
+
+typedef enum _gcSHADER_TYPE_KIND
+{
+    gceTK_UNKOWN,
+    gceTK_FLOAT,
+    gceTK_INT,
+    gceTK_UINT,
+    gceTK_BOOL,
+    gceTK_FIXED,
+    gceTK_IMAGE,
+    gceTK_IMAGE_T,
+    gceTK_SAMPLER,
+    gceTK_SAMPLER_T,
+    gceTK_ATOMIC, /* Atomic Counter */
+    gceTK_INT64,
+    gceTK_UINT64,
+    gceTK_CHAR,
+    gceTK_UCHAR,
+    gceTK_SHORT,
+    gceTK_USHORT,
+    gceTK_FLOAT16,
+    gceTK_OTHER
+} gcSHADER_TYPE_KIND;
+
+typedef struct _gcSHADER_TYPEINFO
+{
+    gcSHADER_TYPE      type;              /* e.g. gcSHADER_FLOAT_2X4 */
+    gctUINT            components;        /* e.g. 4 components each row
+                                           * for packed type it is real component
+                                           * number in vec4 register: CHAR_P3 takes 1
+                                           * component */
+    gctUINT            packedComponents;  /* number of components in packed type,
+                                           * it is 3 for CHAR_P3.
+                                           * same as components for non-packed type */
+    gctUINT            rows;              /* e.g. 2 rows             */
+    gcSHADER_TYPE      rowType;           /* e.g. gcSHADER_FLOAT_X4  */
+    gcSHADER_TYPE      componentType;     /* e.g. gcSHADER_FLOAT_X1  */
+    gcSHADER_TYPE_KIND kind;              /* e.g. gceTK_FLOAT */
+    gctCONST_STRING    name;              /* e.g. "FLOAT_2X4" */
+    gctBOOL            isPacked;          /* e.g. gcvTRUE if of packed type such as gcSHADER_UINT8_P2 ... */
+} gcSHADER_TYPEINFO;
+
+extern const gcSHADER_TYPEINFO gcvShaderTypeInfo[];
+
+#define gcmType_Comonents(Type)         (gcvShaderTypeInfo[Type].components)
+#define gcmType_PackedComonents(Type)   (gcvShaderTypeInfo[Type].packedComponents)
+#define gcmType_Rows(Type)              (gcvShaderTypeInfo[Type].rows)
+#define gcmType_RowType(Type)           (gcvShaderTypeInfo[Type].rowType)
+#define gcmType_ComonentType(Type)      (gcvShaderTypeInfo[Type].componentType)
+#define gcmType_Kind(Type)              (gcvShaderTypeInfo[Type].kind)
+#define gcmType_Name(Type)              (gcvShaderTypeInfo[Type].name)
+
+#define gcmType_isSampler(Type)         (gcmType_Kind(Type) == gceTK_SAMPLER || gcmType_Kind(Type) == gceTK_SAMPLER_T)
+
+#define gcmType_ComponentByteSize       4
+
+#define gcmType_isMatrix(type) (gcmType_Rows(type) > 1)
+
+enum gceLTCDumpOption {
+    gceLTC_DUMP_UNIFORM      = 0x0001,
+    gceLTC_DUMP_EVALUATION   = 0x0002,
+    gceLTC_DUMP_EXPESSION    = 0x0004,
+    gceLTC_DUMP_COLLECTING   = 0x0008,
+};
+
+/* single precision floating point NaN, Infinity, etc. constant */
+#define SINGLEFLOATPOSITIVENAN      0x7fc00000
+#define SINGLEFLOATNEGTIVENAN       0xffc00000
+#define SINGLEFLOATPOSITIVEINF      0x7f800000
+#define SINGLEFLOATNEGTIVEINF       0xff800000
+#define SINGLEFLOATPOSITIVEZERO     0x00000000
+#define SINGLEFLOATNEGTIVEZERO      0x80000000
+
+#define isF32PositiveNaN(f)  (*(gctUINT *)&(f) == SINGLEFLOATPOSITIVENAN)
+#define isF32NegativeNaN(f)  (*(gctUINT *)&(f) == SINGLEFLOATNEGTIVENAN)
+#define isF32NaN(f)  (isF32PositiveNaN(f) || isF32NegativeNaN(f))
+
+#define FLOAT_NaN   (SINGLEFLOATPOSITIVENAN)
+#ifndef INT32_MAX
+#define INT32_MAX   (0x7fffffff)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN   (-0x7fffffff-1)
+#endif
+
+gceSTATUS gcOPT_GetUniformSrcLTC(
+    IN gcSHADER              Shader,
+    IN gctUINT               ltcInstIdx,
+    IN gctINT                SourceId,
+    IN PLTCValue             Results,
+    OUT gcUNIFORM*           RetUniform,
+    OUT gctINT*              RetCombinedOffset,
+    OUT gctINT*              RetConstOffset,
+    OUT gctINT*              RetIndexedOffset,
+    OUT PLTCValue            SourceValue
+    );
+
+gceSTATUS gcOPT_DoConstantFoldingLTC(
+    IN gcSHADER              Shader,
+    IN gctUINT               ltcInstIdx,
+    IN PLTCValue             source0Value, /* set by driver if src0 is app's uniform */
+    IN PLTCValue             source1Value, /* set by driver if src1 is app's uniform */
+    IN PLTCValue             source2Value, /* set by driver if src2 is app's uniform */
+    IN gctBOOL               hasSource2,
+    OUT PLTCValue            resultValue, /* regarded as register file */
+    IN OUT PLTCValue         Results
+    );
+
+gctBOOL gcDumpOption(gctINT Opt);
+
+/* It must be non-zero */
+#define POINTSPRITE_TEX_ATTRIBUTE     0x8000
+
+/* Shader flags. */
+typedef enum _gceSHADER_FLAGS
+{
+    gcvSHADER_NO_OPTIMIZATION           = 0x00,
+    gcvSHADER_DEAD_CODE                 = 0x01,
+    gcvSHADER_RESOURCE_USAGE            = 0x02,
+    gcvSHADER_OPTIMIZER                 = 0x04,
+    gcvSHADER_USE_GL_Z                  = 0x08,
+    /*
+        The GC family of GPU cores model GC860 and under require the Z
+        to be from 0 <= z <= w.
+        However, OpenGL specifies the Z to be from -w <= z <= w.  So we
+        have to a conversion here:
+
+            z = (z + w) / 2.
+
+        So here we append two instructions to the vertex shader.
+    */
+    gcvSHADER_USE_GL_POSITION           = 0x10,
+    gcvSHADER_USE_GL_FACE               = 0x20,
+    gcvSHADER_USE_GL_POINT_COORD        = 0x40,
+    gcvSHADER_LOADTIME_OPTIMIZER        = 0x80,
+#if gcdALPHA_KILL_IN_SHADER
+    gcvSHADER_USE_ALPHA_KILL            = 0x100,
+#endif
+
+    gcvSHADER_ENABLE_MULTI_GPU          = 0x200,
+
+    gcvSHADER_TEXLD_W                   = 0x400,
+
+    gcvSHADER_INT_ATTRIBUTE_W           = 0x800,
+
+    /* The Shader is patched by recompilation. */
+    gcvSHADER_IMAGE_PATCHING            = 0x1000,
+
+    /* Remove unused uniforms on shader, only enable for es20 shader. */
+    gcvSHADER_REMOVE_UNUSED_UNIFORMS    = 0x2000,
+
+    /* Force linking when either vertex or fragment shader not present */
+    gcvSHADER_FORCE_LINKING             = 0x4000,
+
+    /* Disable default UBO for vertex and fragment shader. */
+    gcvSHADER_DISABLE_DEFAULT_UBO       = 0x8000,
+
+    /* This shader is from recompier. */
+    gcvSHADER_RECOMPILER                = 0x10000,
+
+    /* This is a seperated program link */
+    gcvSHADER_SEPERATED_PROGRAM         = 0x20000,
+
+    /* disable dual16 for this ps shader */
+    gcvSHADER_DISABLE_DUAL16            = 0x40000,
+
+    /* set inline level 0 */
+    gcvSHADER_SET_INLINE_LEVEL_0        = 0x80000,
+
+    /* set inline level 1 */
+    gcvSHADER_SET_INLINE_LEVEL_1        = 0x100000,
+
+    /* set inline level 2 */
+    gcvSHADER_SET_INLINE_LEVEL_2        = 0x200000,
+
+    /* set inline level 3 */
+    gcvSHADER_SET_INLINE_LEVEL_3        = 0x400000,
+
+    /* set inline level 4 */
+    gcvSHADER_SET_INLINE_LEVEL_4        = 0x800000,
+
+    /* resets inline level to default */
+    gcvSHADER_RESET_INLINE_LEVEL        = 0x1000000,
+
+    /* Need add robustness check code */
+    gcvSHADER_NEED_ROBUSTNESS_CHECK     = 0x2000000,
+
+    /* Denormalize flag */
+    gcvSHADER_FLUSH_DENORM_TO_ZERO      = 0x4000000,
+
+    /* Has image in kernel source code of OCL kernel program */
+    gcSHADER_HAS_IMAGE_IN_KERNEL        = 0x8000000,
+
+    gcvSHADER_VIRCG_NONE                = 0x10000000,
+    gcvSHADER_VIRCG_ONE                 = 0x20000000,
+
+    gcvSHADER_MIN_COMP_TIME             = 0x40000000,
+
+    /* Link program pipeline object. */
+    gcvSHADER_LINK_PROGRAM_PIPELINE_OBJ = 0x80000000,
+}
+gceSHADER_FLAGS;
+
+typedef struct _gceSHADER_SUB_FLAGS
+{
+    gctUINT     dual16PrecisionRule;
+}
+gceSHADER_SUB_FLAGS;
+
+#if gcdUSE_WCLIP_PATCH
+gceSTATUS
+gcSHADER_CheckClipW(
+    IN gctCONST_STRING VertexSource,
+    IN gctCONST_STRING FragmentSource,
+    OUT gctBOOL * clipW);
+#endif
+
+/*******************************************************************************
+**                            gcOptimizer Data Structures
+*******************************************************************************/
+typedef enum _gceSHADER_OPTIMIZATION
+{
+    /*  No optimization. */
+    gcvOPTIMIZATION_NONE,
+
+    /*  Dead code elimination. */
+    gcvOPTIMIZATION_DEAD_CODE                   = 1 << 0,
+
+    /*  Redundant move instruction elimination. */
+    gcvOPTIMIZATION_REDUNDANT_MOVE              = 1 << 1,
+
+    /*  Inline expansion. */
+    gcvOPTIMIZATION_INLINE_EXPANSION            = 1 << 2,
+
+    /*  Constant propagation. */
+    gcvOPTIMIZATION_CONSTANT_PROPAGATION        = 1 << 3,
+
+    /*  Redundant bounds/checking elimination. */
+    gcvOPTIMIZATION_REDUNDANT_CHECKING          = 1 << 4,
+
+    /*  Vector component operation merge. */
+    gcvOPTIMIZATION_VECTOR_INSTRUCTION_MERGE    = 1 << 5,
+
+    /*  Loadtime constant. */
+    gcvOPTIMIZATION_LOADTIME_CONSTANT           = 1 << 6,
+
+    /*  MAD instruction optimization. */
+    gcvOPTIMIZATION_MAD_INSTRUCTION             = 1 << 7,
+
+    gcvOPTIMIZATION_LOAD_SW_W                   = 1 << 8,
+
+    /*  Move code into conditional block if possile */
+    gcvOPTIMIZATION_CONDITIONALIZE              = 1 << 9,
+
+    /*  Expriemental: power optimization mode
+        1. add extra dummy texld to tune performance
+        2. insert NOP after high power instrucitons
+        3. split high power vec3/vec4 instruciton to vec2/vec1 operation
+        4. ...
+     */
+    gcvOPTIMIZATION_POWER_OPTIMIZATION          = 1 << 10,
+
+    /*  Update precision */
+    gcvOPTIMIZATION_UPDATE_PRECISION            = 1 << 11,
+
+    /*  Loop rerolling */
+    gcvOPTIMIZATION_LOOP_REROLLING              = 1 << 12,
+
+    /*  Image patching: */
+    /*     Inline functions using IMAGE_READ or IMAGE_WRITE. */
+    gcvOPTIMIZATION_IMAGE_PATCHING              = 1 << 13,
+
+    /*  Optimize a recompiler shader. */
+    gcvOPTIMIZATION_RECOMPILER                  = 1 << 14,
+
+    /*  Constant argument propagation. */
+    gcvOPTIMIZATION_CONSTANT_ARGUMENT_PROPAGATION = 1 << 15,
+
+    /* Inline level setting. */
+    gcvOPTIMIZATION_INLINE_LEVEL_0              = 1 << 16,
+    gcvOPTIMIZATION_INLINE_LEVEL_1              = 1 << 17,
+    gcvOPTIMIZATION_INLINE_LEVEL_2              = 1 << 18,
+    gcvOPTIMIZATION_INLINE_LEVEL_3              = 1 << 19,
+    gcvOPTIMIZATION_INLINE_LEVEL_4              = 1 << 20,
+
+    gcvOPTIMIZATION_MIN_COMP_TIME               = 1 << 21,
+
+    /*  Full optimization. */
+    /*  Note that gcvOPTIMIZATION_LOAD_SW_W is off. */
+    gcvOPTIMIZATION_FULL                        = 0x7FFFFFFF &
+                                                  ~gcvOPTIMIZATION_LOAD_SW_W &
+                                                  ~gcvOPTIMIZATION_POWER_OPTIMIZATION &
+                                                  ~gcvOPTIMIZATION_IMAGE_PATCHING &
+                                                  ~gcvOPTIMIZATION_RECOMPILER &
+                                                  ~gcvOPTIMIZATION_INLINE_LEVEL_0 &
+                                                  ~gcvOPTIMIZATION_INLINE_LEVEL_1 &
+                                                  ~gcvOPTIMIZATION_INLINE_LEVEL_2 &
+                                                  ~gcvOPTIMIZATION_INLINE_LEVEL_3 &
+                                                  ~gcvOPTIMIZATION_INLINE_LEVEL_4 &
+                                                  ~gcvOPTIMIZATION_MIN_COMP_TIME
+,
+
+    /* Optimization Unit Test flag. */
+    gcvOPTIMIZATION_UNIT_TEST                   = 1 << 31
+
+}
+gceSHADER_OPTIMIZATION;
+
+typedef enum _gceOPTIMIZATION_VaryingPaking
+{
+    gcvOPTIMIZATION_VARYINGPACKING_NONE = 0,
+    gcvOPTIMIZATION_VARYINGPACKING_NOSPLIT,
+    gcvOPTIMIZATION_VARYINGPACKING_SPLIT
+} gceOPTIMIZATION_VaryingPaking;
+
+
+/* The highp in the shader appear because
+   1) APP defined as highp
+   2) promote from mediump per HW requirements
+   3) promote from mediump based on the following rules.
+      These rules can be disabled individually.
+      Driver will detect benchmark and shader and set
+      these rules accordingly.
+      VC_OPTION can override these rules.
+   */
+typedef enum _Dual16_PrecisionRule
+{
+    /*  No dual16 highp rules applied. */
+    Dual16_PrecisionRule_NONE                   = 0,
+
+    /*  promote the texld coordiante (from varying) to highp */
+    Dual16_PrecisionRule_TEXLD_COORD_HP         = 1 << 0,
+
+    /*  promote rcp src/dest to highp */
+    Dual16_PrecisionRule_RCP_HP                 = 1 << 1,
+
+    /*  promote frac src/dest to highp */
+    Dual16_PrecisionRule_FRAC_HP                = 1 << 2,
+
+    /*  immediate is always highp */
+    Dual16_PrecisionRule_IMMED_HP               = 1 << 3,
+
+    /*  immediate is always mediump */
+    Dual16_PrecisionRule_IMMED_MP               = 1 << 4,
+
+    /* HW Cvt2OutColFmt has issue with 0x2,
+    thus require output to be highp */
+    Dual16_PrecisionRule_OUTPUT_HP              = 1 << 5,
+
+    /*  default rules */
+    Dual16_PrecisionRule_DEFAULT                = Dual16_PrecisionRule_TEXLD_COORD_HP |
+                                                  Dual16_PrecisionRule_RCP_HP         |
+                                                  Dual16_PrecisionRule_FRAC_HP,
+
+    /*  applied all rules */
+    Dual16_PrecisionRule_FULL                   = Dual16_PrecisionRule_TEXLD_COORD_HP |
+                                                  Dual16_PrecisionRule_RCP_HP         |
+                                                  Dual16_PrecisionRule_FRAC_HP        |
+                                                  Dual16_PrecisionRule_IMMED_HP,
+
+}
+Dual16_PrecisionRule;
+
+typedef struct _ShaderSourceList ShaderSourceList;
+struct _ShaderSourceList
+{
+    gctINT             shaderId;
+    gctINT             sourceSize;
+    gctCHAR *          src;
+    gctSTRING          fileName;
+    ShaderSourceList * next;
+};
+enum MacroDefineKind
+{
+    MDK_Define,
+    MDK_Undef
+};
+
+typedef struct _MacroDefineList MacroDefineList;
+struct _MacroDefineList
+{
+    enum MacroDefineKind kind;
+    gctCHAR *            str;    /* name[=value] */
+    MacroDefineList *    next;
+};
+
+enum ForceInlineKind
+{
+    FIK_None,
+    FIK_Inline,
+    FIK_NotInline
+};
+
+typedef struct _InlineStringList InlineStringList;
+struct _InlineStringList
+{
+    enum ForceInlineKind kind;
+    gctCHAR *            func;   /* function name to force inline/notInline */
+    InlineStringList *   next;
+};
+
+typedef enum _VIRCGKind
+{
+    VIRCG_None          = 0,
+    VIRCG_DEFAULT       = 1,
+    VIRCG_WITH_TREECG   = 1, /* go through VIR pass, but use gcSL LinkerTree to generate MC */
+    VIRCG_FULL          = 2, /* go through VIR pass and use VIR Full linker to generate MC */
+}VIRCGKind;
+
+typedef struct _gcOPTIMIZER_OPTION
+{
+    gceSHADER_OPTIMIZATION     optFlags;
+
+    /* debug & dump options:
+
+         VC_OPTION=-DUMP:SRC|:IR|:OPT|:OPTV|:CG|:CGV|:HTP|:ALL|:ALLV|:UNIFORM|:T[-]m,n|RENUM:[0|1]
+
+         SRC:  dump shader source code
+         IR:   dump final IR
+         SRCLOC: dump IR's corresponding source location
+         OPT:  dump incoming and final IR
+         OPTV: dump result IR in each optimization phase
+         CG:   dump generated machine code
+         CGV:  dump BE tree and optimization detail
+         HTP:  dump hash table performance
+         LOG:  dump FE log file in case of compiler error
+         Tm:   turn on dump for shader id m
+         Tm,n: turn on dump for shader id is in range of [m, n]
+         T-m:  turn off dump for shader id m
+         T-m,n: turn off dump for shader id is in range of [m, n]
+         ALL = SRC|OPT|CG|LOG
+         ALLV = SRC|OPT|OPTV|CG|CGV|LOG
+
+         UNIFORM: dump uniform value when setting uniform
+         RENUM:[0|1]: re-number instruction id when dumping IR
+     */
+    gctBOOL     dumpShaderSource;      /* dump shader source code */
+    gctBOOL     dumpOptimizer;         /* dump incoming and final IR */
+    gctBOOL     dumpOptimizerVerbose;  /* dump result IR in each optimization phase */
+    gctBOOL     dumpBEGenertedCode;    /* dump generated machine code */
+    gctBOOL     dumpBEVerbose;         /* dump BE tree and optimization detail */
+    gctBOOL     dumpBEFinalIR;         /* dump BE final IR */
+    gctBOOL     dumpSrcLoc;            /* dump IR instruction's corresponding source location*/
+    gctBOOL     dumpFELog;             /* dump FE log file in case of compiler error */
+    gctBOOL     dumpPPedStr2File;      /* dump FE preprocessed string to file */
+    gctBOOL     dumpUniform;           /* dump uniform value when setting uniform */
+    gctBOOL     dumpSpirvIR;           /* dump VIR shader convert from SPIRV */
+    gctBOOL     dumpSpirvToFile;       /* dump SPRIV to file */
+    gctBOOL     dumpBinToFile;         /* dump program binary to file when calling gcLoadProgram */
+    gctBOOL     dumpHashPerf;          /* dump hash table performance */
+    gctINT      _dumpStart;            /* shader id start to dump */
+    gctINT      _dumpEnd;              /* shader id end to dump */
+    gctINT      renumberInst;          /* re-number instruction when dumping IR */
+    gctINT      includeLib;            /* dump library shader too (library shader won't be dumped by default) */
+
+    /* Code generation */
+
+    /* Varying Packing:
+
+          VC_OPTION=-PACKVARYING:[0-2]|:T[-]m[,n]|:LshaderIdx,min,max
+
+          0: turn off varying packing
+          1: pack varyings, donot split any varying
+          2: pack varyings, may split to make fully packed output
+
+          Tm:    only packing shader pair which vertex shader id is m
+          Tm,n:  only packing shader pair which vertex shader id
+                   is in range of [m, n]
+          T-m:   do not packing shader pair which vertex shader id is m
+          T-m,n: do not packing shader pair which vertex shader id
+                   is in range of [m, n]
+
+          LshaderIdx,min,max : set  load balance (min, max) for shaderIdx
+                               if shaderIdx is -1, all shaders are impacted
+                               newMin = origMin * (min/100.);
+                               newMax = origMax * (max/100.);
+     */
+    gceOPTIMIZATION_VaryingPaking    packVarying;
+    gctINT                           _triageStart;
+    gctINT                           _triageEnd;
+    gctINT                           _loadBalanceShaderIdx;
+    gctINT                           _loadBalanceMin;
+    gctINT                           _loadBalanceMax;
+
+    /* Do not generate immdeiate
+
+          VC_OPTION=-NOIMM
+
+       Force generate immediate even the machine model don't support it,
+       for testing purpose only
+
+          VC_OPTION=-FORCEIMM
+     */
+    gctBOOL     noImmediate;
+    gctBOOL     forceImmediate;
+
+    /* Power reduction mode options */
+    gctBOOL   needPowerOptimization;
+
+     /* If need to dump hash table performance, set hash table max search times,
+        and if the fact search times is more than the max times, also add the number of max search times up,
+        if not to set this option, the max search times is 0, that means can not to statistic search times
+
+              VC_OPTION=-HMST:value
+    */
+    gctINT      hashMaxSearchTimes;
+
+    /* Patch TEXLD instruction by adding dummy texld
+       (can be used to tune GPU power usage):
+         for every TEXLD we seen, add n dummy TEXLD
+
+        it can be enabled by environment variable:
+
+          VC_OPTION=-PATCH_TEXLD:M:N
+
+        (for each M texld, add N dummy texld)
+     */
+    gctINT      patchEveryTEXLDs;
+    gctINT      patchDummyTEXLDs;
+
+    /* Insert NOP after high power consumption instructions
+
+         VC_OPTION="-INSERTNOP:MUL:MULLO:DP3:DP4:SEENTEXLD"
+     */
+    gctBOOL     insertNOP;
+    gctBOOL     insertNOPAfterMUL;
+    gctBOOL     insertNOPAfterMULLO;
+    gctBOOL     insertNOPAfterDP3;
+    gctBOOL     insertNOPAfterDP4;
+    gctBOOL     insertNOPOnlyWhenTexldSeen;
+
+    /* split MAD to MUL and ADD:
+
+         VC_OPTION=-SPLITMAD
+     */
+    gctBOOL     splitMAD;
+
+    /* Convert vect3/vec4 operations to multiple vec2/vec1 operations
+
+         VC_OPTION=-SPLITVEC:MUL:MULLO:DP3:DP4
+     */
+    gctBOOL     splitVec;
+    gctBOOL     splitVec4MUL;
+    gctBOOL     splitVec4MULLO;
+    gctBOOL     splitVec4DP3;
+    gctBOOL     splitVec4DP4;
+
+    /* turn/off features:
+
+          VC_OPTION=-F:n,[0|1]
+          Note: n must be decimal number
+     */
+    gctUINT     featureBits;
+
+    /* Replace specified shader's source code with the contents in
+       specified file:
+
+         VC_OPTION=-SHADER:id1,file1[:id2,file ...]
+
+    */
+    ShaderSourceList * shaderSrcList;
+
+    /* Load-time Constant optimization:
+
+        VC_OPTION=-LTC:0|1
+
+    */
+    gctBOOL     enableLTC;
+
+    /* debug option:
+
+        VC_OPTION=-DEBUG:0|1|2|3
+
+    */
+    gctUINT     enableDebug;
+
+    /* VC_OPTION=-Ddef1[=value1] -Ddef2[=value2] -Uundef1 */
+    MacroDefineList * macroDefines;
+
+    /* inliner kind (default 1 VIR inliner):
+
+          VC_OPTION=-INLINER:[0-1]
+             0:  gcsl inliner
+             1:  VIR inliner
+
+        When VIRCG is not enabled, gcsl inliner is always used.
+     */
+    gctUINT     inlinerKind;
+
+    /* inline level (default 2 at O1):
+
+          VC_OPTION=-INLINELEVEL:[0-4]
+             0:  no inline
+             1:  only inline the function only called once or small function
+             2:  inline functions be called less than 5 times or medium size function
+             3:  inline everything possible within inline budget
+             4:  inline everything possible disregard inline budget
+     */
+    gctUINT     inlineLevel;
+
+    /* inline recompilation functions for depth comparison if inline level is not 0.
+       (default 1)
+
+          VC_OPTION=-INLINEDEPTHCOMP:[0-3]
+             0:  follows inline level
+             1:  inline depth comparison functions for halti2
+             2:  inline depth comparison functions for halti1
+             3:  inline depth comparison functions for halti0
+     */
+    gctBOOL     inlineDepthComparison;
+
+    /* inline recompilation functions for format conversion if inline level is not 0.
+       (default 1)
+
+          VC_OPTION=-INLINEFORMATCONV:[0-3]
+             0:  follows inline level
+             1:  inline format conversion functions for halti2
+             2:  inline format conversion functions for halti1
+             3:  inline format conversion functions for halti0
+     */
+    gctUINT     inlineFormatConversion;
+
+    /* this is a test only option
+
+       VC_OPTION=-TESSLEVEL:x
+       default: GC_DEFAULT_TESS_LEVEL
+
+       set the gl_TessLevelOuter and gl_TessLevelInner to be this value
+       when it is not GC_DEFAULT_TESS_LEVEL
+    */
+    gctUINT     testTessLevel;
+
+    /* dual 16 mode
+     *
+     *    VC_OPTION=-DUAL16:[0-3]
+     *       0:  force dual16 off.
+     *       1:  auto-on mode for specific benchmarks.
+     *       2:  auto-on mode for all applications.
+     *       3:  force dual16 on for all applications ignoring the heuristic.
+     */
+    gctBOOL     dual16Specified;
+    gctUINT     dual16Mode;
+    gctINT      _dual16Start;           /* shader id start to enable dual16 */
+    gctINT      _dual16End;             /* shader id end to enalbe dual16 */
+
+    /* dual 16 highp rule
+    *
+    *    VC_OPTION=-HPDUAL16:[0-x]
+    *       0: no dual16 highp rules applied
+    *       1: Dual16_PrecisionRule_TEXLD_COORD_HP
+    *       2: Dual16_PrecisionRule_RCP_HP
+    *       4: Dual16_PrecisionRule_FRAC_HP
+    *       8: Dual16_PrecisionRule_IMMED_HP
+    *       default is Dual16_PrecisionRule_FULL
+    *           (which is Dual16_PrecisionRule_TEXLD_COORD_HP |
+    *                     Dual16_PrecisionRule_RCP_HP         |
+    *                     Dual16_PrecisionRule_FRAC_HP        |
+    *                     Dual16_PrecisionRule_IMMED_HP)
+    */
+    gctUINT     dual16PrecisionRule;
+
+    /* whether the user set dual16PrecisionRule */
+    gctBOOL     dual16PrecisionRuleFromEnv;
+
+    /* force inline or not inline a function
+     *
+     *   VC_OPTION=-FORCEINLINE:func[,func]*
+     *
+     *   VC_OPTION=-NOTINLINE:func[,func]*
+     *
+     */
+    InlineStringList *   forceInline;
+
+    /* Upload Uniform Block to state buffer if there are space available
+     * Doing this may potentially improve the performance as the load
+     * instruction for uniform block member can be removed.
+     *
+     *   VC_OPTION=-UPLOADUBO:0|1
+     *
+     */
+    gctBOOL     uploadUBO;
+
+    /* OpenCL floating point capabilities setting
+     * FASTRELAXEDMATH => -cl-fast-relaxed-math option
+     * FINITEMATHONLY => -cl-finite-math-only option
+     * RTNE => Round To Even
+     * RTZ => Round to Zero
+     *
+     * VC_OPTION=-OCLFPCAPS:FASTRELAXEDMATH:FINITEMATHONLY:RTNE:RTZ
+     */
+    gctUINT     oclFpCaps;
+
+    /* use VIR code generator:
+     *
+     *   VC_OPTION=-VIRCG:[0|1]|T[-]m[,n]
+     *    Tm:    turn on VIRCG for shader id m
+     *    Tm,n:  turn on VIRCG for shader id is in range of [m, n]
+     *    T-m:   turn off VIRCG for shader id m
+     *    T-m,n: turn off VIRCG for shader id is in range of [m, n]
+     *
+     */
+    VIRCGKind   useVIRCodeGen;
+    /* useVIRCodeGen maybe changed for specific test, we need to save the orignal option */
+    VIRCGKind   origUseVIRCodeGen;
+
+    gctBOOL     virCodeGenSpecified;
+    gctINT      _vircgStart;
+    gctINT      _vircgEnd;
+
+    /* create default UBO:
+     *
+     *   VC_OPTION=-CREATEDEAULTUBO:0|1
+     *
+     */
+    gctBOOL     createDefaultUBO;
+
+    /*
+     * Handle OCL basic type as packed
+     *
+     *   VC_OPTION=-OCLPACKEDBASICTYPE:0|1
+     *
+     */
+    gctBOOL     oclPackedBasicType;
+
+    /*
+     * Handle OCL  relaxing local address space in OCV
+     *
+     *   VC_OPTION=-OCLOCVLOCALADDRESSSPACE:0|1
+     *
+     */
+    gctBOOL    oclOcvLocalAddressSpace;
+
+    /*
+     * Handle OCL  in OPENCV
+     *
+     *   VC_OPTION=-OCLOPENCV:0|1
+     *
+     */
+    gctBOOL    oclOpenCV;
+
+    /*  OCL has long:
+     *
+     *   VC_OPTION=-OCLHASLONG:0|1
+     *
+     */
+    gctBOOL     oclHasLong;
+
+    /*  OCL long and ulong support in VIR:
+     *
+     *   VC_OPTION=-OCLINT64INVIR:0|1
+     *
+     */
+    gctBOOL     oclInt64InVir;
+
+    /*  OCL uniforms for constant address space variables
+     *
+     *   VC_OPTION=-OCLUNIFORMFORCONSTANT:0|1
+     *
+     */
+    gctBOOL     oclUniformForConstant;
+
+    /*  USE gcSL_NEG for -a instead of SUB(0, a)
+     *
+     *   VC_OPTION=-OCLUSENEG
+     *
+     */
+    gctBOOL     oclUseNeg;
+
+    /*  USE img intrinsic query function for OCL
+     *
+     *   VC_OPTION=-OCLUSEIMG_INTRINSIC_QUERY:0|1
+     *
+     */
+    gctBOOL     oclUseImgIntrinsicQuery;
+
+    /*  Pass kernel struct arguments by value in OCL
+     *
+     *   VC_OPTION=-OCLPASS_KERNEL_STRUCT_ARG_BY_VALUE:0|1
+     *
+     */
+    gctBOOL     oclPassKernelStructArgByValue;
+
+    /*  Treat half types as floats in OCL
+     *
+     *   VC_OPTION=-OCLTREAT_HALF_AS_FLOAT:0|1
+     *
+    */
+    gctBOOL     oclTreatHalfAsFloat;
+
+    /* Specify the log file name
+     *
+     *   VC_OPTION=-LOG:filename
+     */
+    gctSTRING   logFileName;
+    gctFILE     debugFile;
+
+    /* turn on/off shader patch:
+     *   VC_OPTION=-PATCH:[0|1]|T[-]m[,n]
+     *    Tm:    turn on shader patch for shader id m
+     *    Tm,n:  turn on shader patch for shader id is in range of [m, n]
+     *    T-m:   turn off shader patch for shader id m
+     *    T-m,n: turn off shader patch for shader id is in range of [m, n]
+     */
+    gctBOOL     patchShader;
+    gctINT      _patchShaderStart;
+    gctINT      _patchShaderEnd;
+
+    /* set default fragment shader floating point precision if not specified in shader
+     *   VC_OPTION=-FRAGMENT_FP_PRECISION:[highp|mediump|lowp]
+     *    highp: high precision
+     *    mediump:  medium precision
+     *    lowp:   low precision
+     */
+    gcSHADER_PRECISION   fragmentFPPrecision;
+
+    /* OCL use VIR code generator:
+     *
+     *   VC_OPTION=-CLVIRCG:[0|1]|T[-]m[,n]
+     *    Tm:    turn on VIRCG for OCL shader id m
+     *    Tm,n:  turn on VIRCG for OCL shader id is in range of [m, n]
+     *    T-m:   turn off VIRCG for OCL shader id m
+     *    T-m,n: turn off VIRCG for OCL shader id is in range of [m, n]
+     */
+    gctBOOL     CLUseVIRCodeGen;
+
+    /* Enable register pack in old compiler:
+
+        VC_OPTION=-PACKREG:0|1
+
+    */
+    gctBOOL     enablePackRegister;
+
+    /* Operate shader files :
+     *
+     * VC_OPTION=-LIBSHADERFILE:0|1|2
+     *  0:  Unable to operate shader files
+     *  1:  Enable write/read Shader info to/from file
+     *  2:  Force rewrite shader info to file
+     */
+    gctINT     libShaderFile;
+
+    /* whether driver use new VIR path for driver programming
+     * passed in by driver
+     */
+    gctBOOL     DriverVIRPath;
+
+    /* NOTE: when you add a new option, you MUST initialize it with default
+       value in theOptimizerOption too */
+} gcOPTIMIZER_OPTION;
+
+/* DUAL16_FORCE_OFF:  turn off dual16
+   DUAL16_AUTO_BENCH: turn on dual16 for selected benchmarks
+   DUAL16_AUTO_ALL:   turn on dual16 for all
+   DUAL16_FORCE_ON:   we have heuristic to turn off dual16 if the single-t instructions are too many,
+                      this option will ignore the heuristic
+*/
+#define DUAL16_FORCE_OFF            0
+#define DUAL16_AUTO_BENCH           1
+#define DUAL16_AUTO_ALL             2
+#define DUAL16_FORCE_ON             3
+
+#define VC_OPTION_OCLFPCAPS_FASTRELAXEDMATH     (1 << 0 )
+#define VC_OPTION_OCLFPCAPS_FINITEMATHONLY      (1 << 1 )
+#define VC_OPTION_OCLFPCAPS_ROUNDTOEVEN         (1 << 2 )
+#define VC_OPTION_OCLFPCAPS_ROUNDTOZERO         (1 << 3 )
+#define VC_OPTION_OCLFPCAPS_NOFASTRELAXEDMATH   (1 << 4 )
+
+#define GCSL_INLINER_KIND        0
+#define VIR_INLINER_KIND         1
+
+extern gcOPTIMIZER_OPTION theOptimizerOption;
+
+#define gcmGetOptimizerOption() gcGetOptimizerOption()
+#define gcmGetOptimizerOptionVariable() gcGetOptimizerOptionVariable()
+
+#define gcmOPT_DUMP_Start()     (gcmGetOptimizerOption()->_dumpStart)
+#define gcmOPT_DUMP_End()     (gcmGetOptimizerOption()->_dumpEnd)
+
+#define gcmOPT_DUMP_SHADER_SRC()        (gcmGetOptimizerOption()->dumpShaderSource != 0)
+#define gcmOPT_DUMP_OPTIMIZER_VERBOSE() (gcmGetOptimizerOption()->dumpOptimizerVerbose != 0)
+#define gcmOPT_DUMP_OPTIMIZER()         (gcmGetOptimizerOption()->dumpOptimizer != 0 || gcmOPT_DUMP_OPTIMIZER_VERBOSE())
+#define gcmOPT_DUMP_CODEGEN_VERBOSE()   (gcmGetOptimizerOption()->dumpBEVerbose != 0)
+#define gcmOPT_DUMP_CODEGEN()           (gcmGetOptimizerOption()->dumpBEGenertedCode != 0 || gcmOPT_DUMP_CODEGEN_VERBOSE())
+#define gcmOPT_DUMP_FINAL_IR()          (gcmGetOptimizerOption()->dumpBEFinalIR != 0)
+#define gcmOPT_DUMP_UNIFORM()           (gcmGetOptimizerOption()->dumpUniform != 0)
+#define gcmOPT_DUMP_FELOG()             (gcmGetOptimizerOption()->dumpFELog != 0)
+#define gcmOPT_DUMP_PPEDSTR2FILE()      (gcmGetOptimizerOption()->dumpPPedStr2File != 0)
+#define gcmOPT_DUMP_SRCLOC()            (gcmGetOptimizerOption()->dumpSrcLoc != 0)
+
+#define gcmOPT_SET_DUMP_SHADER_SRC(v)   (gcmGetOptimizerOption()->dumpShaderSource = (v)
+
+#define gcmOPT_PATCH_TEXLD()  (gcmGetOptimizerOption()->patchDummyTEXLDs != 0)
+#define gcmOPT_INSERT_NOP()   (gcmGetOptimizerOption()->insertNOP == gcvTRUE)
+#define gcmOPT_SPLITMAD()     (gcmGetOptimizerOption()->splitMAD == gcvTRUE)
+#define gcmOPT_SPLITVEC()     (gcmGetOptimizerOption()->splitVec == gcvTRUE)
+
+#define gcmOPT_NOIMMEDIATE()  (gcmGetOptimizerOption()->noImmediate == gcvTRUE)
+#define gcmOPT_FORCEIMMEDIATE()  (gcmGetOptimizerOption()->forceImmediate == gcvTRUE)
+
+#define gcmOPT_PACKVARYING()     (gcmGetOptimizerOption()->packVarying)
+#define gcmOPT_PACKVARYING_triageStart()   (gcmGetOptimizerOption()->_triageStart)
+#define gcmOPT_PACKVARYING_triageEnd()     (gcmGetOptimizerOption()->_triageEnd)
+#define gcmOPT_SetVaryingPacking(VP)       do { gcmOPT_PACKVARYING() = VP; } while (0)
+
+#define gcmOPT_LB_ShaderIdx()  (gcmGetOptimizerOption()->_loadBalanceShaderIdx)
+#define gcmOPT_LB_Min()        (gcmGetOptimizerOption()->_loadBalanceMin)
+#define gcmOPT_LB_Max()        (gcmGetOptimizerOption()->_loadBalanceMax)
+
+#define gcmOPT_ShaderSourceList() (gcmGetOptimizerOption()->shaderSrcList)
+#define gcmOPT_MacroDefines()     (gcmGetOptimizerOption()->macroDefines)
+
+#define gcmOPT_EnableLTC()          (gcmGetOptimizerOption()->enableLTC)
+#define gcmOPT_EnableDebug()        (gcmGetOptimizerOption()->enableDebug > 0)
+#define gcmOPT_EnableDebugDump()    (gcmGetOptimizerOption()->enableDebug > 1)
+#define gcmOPT_EnableDebugDumpALL() (gcmGetOptimizerOption()->enableDebug > 2)
+#define gcmOPT_EnableDebugMode()    (gcmGetOptimizerOption()->enableDebug == 4)
+#define gcmOPT_INLINERKIND()        (gcmGetOptimizerOption()->inlinerKind)
+#define gcmOPT_INLINELEVEL()        (gcmGetOptimizerOption()->inlineLevel)
+#define gcmOPT_SetINLINELEVEL(v)    (gcmGetOptimizerOptionVariable()->inlineLevel = (v))
+#define gcmOPT_INLINEDEPTHCOMP()    (gcmGetOptimizerOption()->inlineDepthComparison)
+#define gcmOPT_INLINEFORMATCONV()   (gcmGetOptimizerOption()->inlineFormatConversion)
+#define gcmOPT_DualFP16Specified()  (gcmGetOptimizerOption()->dual16Specified)
+#define gcmOPT_DualFP16Mode()       (gcmGetOptimizerOption()->dual16Mode)
+#define gcmOPT_DualFP16Start()      (gcmGetOptimizerOption()->_dual16Start)
+#define gcmOPT_DualFP16End()        (gcmGetOptimizerOption()->_dual16End)
+
+#define gcmOPT_TESSLEVEL()          (gcmGetOptimizerOption()->testTessLevel)
+
+#define gcmOPT_DualFP16PrecisionRule()          (gcmGetOptimizerOption()->dual16PrecisionRule)
+#define gcmOPT_DualFP16PrecisionRuleFromEnv()   (gcmGetOptimizerOption()->dual16PrecisionRuleFromEnv)
+
+#define gcmOPT_ForceInline()        (gcmGetOptimizerOption()->forceInline)
+#define gcmOPT_UploadUBO()          (gcmGetOptimizerOption()->uploadUBO)
+#define gcmOPT_oclFpCaps()          (gcmGetOptimizerOption()->oclFpCaps)
+#define gcmOPT_oclPackedBasicType() (gcmGetOptimizerOption()->oclPackedBasicType)
+#define gcmOPT_oclOcvLocalAddressSpace() (gcmGetOptimizerOption()->oclOcvLocalAddressSpace)
+#define gcmOPT_oclOpenCV()          (gcmGetOptimizerOption()->oclOpenCV)
+#define gcmOPT_oclHasLong()         (gcmGetOptimizerOption()->oclHasLong)
+#define gcmOPT_oclInt64InVIR()      (gcmGetOptimizerOption()->oclInt64InVir)
+#define gcmOPT_oclUniformForConstant()   (gcmGetOptimizerOption()->oclUniformForConstant)
+#define gcmOPT_oclUseNeg()          (gcmGetOptimizerOption()->oclUseNeg)
+#define gcmOPT_oclUseImgIntrinsicQuery()   (gcmGetOptimizerOption()->oclUseImgIntrinsicQuery)
+#define gcmOPT_oclPassKernelStructArgByValue()   (gcmGetOptimizerOption()->oclPassKernelStructArgByValue)
+#define gcmOPT_oclTreatHalfAsFloat()   (gcmGetOptimizerOption()->oclTreatHalfAsFloat)
+#define gcmOPT_UseVIRCodeGen()      (gcmGetOptimizerOption()->useVIRCodeGen)
+#define gcmOPT_VirCodeGenSpecified()(gcmGetOptimizerOption()->virCodeGenSpecified)
+#define gcmOPT_VIRCGStart()         (gcmGetOptimizerOption()->_vircgStart)
+#define gcmOPT_VIRCGEnd()           (gcmGetOptimizerOption()->_vircgEnd)
+#define gcmOPT_CLUseVIRCodeGen()    (gcmGetOptimizerOption()->CLUseVIRCodeGen)
+#define gcmOPT_DriverVIRPath()      (gcmGetOptimizerOption()->DriverVIRPath)
+#define gcmOPT_CreateDefaultUBO()   (gcmGetOptimizerOption()->createDefaultUBO)
+#define gcmOPT_PatchShader()        (gcmGetOptimizerOption()->patchShader)
+#define gcmOPT_PatchShaderStart()   (gcmGetOptimizerOption()->_patchShaderStart)
+#define gcmOPT_PatchShaderEnd()     (gcmGetOptimizerOption()->_patchShaderEnd)
+#define gcmOPT_PackRegister()       (gcmGetOptimizerOption()->enablePackRegister)
+#define gcmOPT_LibShaderFile()       (gcmGetOptimizerOption()->libShaderFile)
+
+#define gcmOPT_SetOclPackedBasicType(val) do { (gcmGetOptimizerOption()->oclPackedBasicType = (val)); } while(0)
+
+#define gcmOPT_FragmentFPPrecision() (gcmGetOptimizerOption()->fragmentFPPrecision)
+
+extern gctBOOL gcSHADER_GoVIRPass(gcSHADER Shader);
+extern gctBOOL gcSHADER_DoPatch(gcSHADER Shader);
+extern gctBOOL gcSHADER_DumpSource(gcSHADER Shader);
+extern gctBOOL gcSHADER_DumpOptimizer(gcSHADER Shader);
+extern gctBOOL gcSHADER_DumpOptimizerVerbose(gcSHADER Shader);
+extern gctBOOL gcSHADER_DumpCodeGen(void * Shader);
+extern gctBOOL gcSHADER_DumpCodeGenVerbose(void * Shader);
+extern gctBOOL VirSHADER_DumpCodeGenVerbose(void * Shader);
+extern gctBOOL gcSHADER_DumpFinalIR(gcSHADER Shader);
+extern gctBOOL VirSHADER_DoDual16(gctINT ShaderId);
+extern gctBOOL gcDoTriageForShaderId(gctINT shaderId, gctINT startId, gctINT endId);
+
+/* Setters */
+/* feature bits */
+#define FB_LIVERANGE_FIX1                   0x0001
+#define FB_INLINE_RENAMETEMP                0x0002
+#define FB_UNLIMITED_INSTRUCTION            0x0004
+#define FB_DISABLE_PATCH_CODE               0x0008
+#define FB_DISABLE_MERGE_CONST              0x0010
+#define FB_DISABLE_OLD_DCE                  0x0020
+#define FB_INSERT_MOV_INPUT                 0x0040  /* insert MOV Rn, Rn for input to help HW team to debug */
+#define FB_ENABLE_FS_OUT_INIT               0x0080  /* enable Fragment shader output
+                                                       initialization if it is un-initialized */
+#define FB_ENABLE_CONST_BORDER              0x0100  /* enable const border value, driver need to set $ConstBorderValue uniform */
+#define FB_FORCE_LS_ACCESS                  0x8000  /* triage use: enforce all load/store as local storage access,
+                                                       remove this feature bit once local storage access is supported */
+#define FB_FORCE_USC_UNALLOC                0x10000 /* triage use: enforce all load/store as USC Unalloc  */
+
+#define FB_TREAT_CONST_ARRAY_AS_UNIFORM     0x20000 /* Treat a const array as a uniform,
+                                                       it can decrease the temp registers but increases the constant registers. */
+#define FB_DISABLE_GL_LOOP_UNROLLING        0x40000 /* Disable loop unrolling for GL FE. */
+
+#define gcmOPT_SetPatchTexld(m,n) (gcmGetOptimizerOption()->patchEveryTEXLDs = (m),\
+                                   gcmGetOptimizerOption()->patchDummyTEXLDs = (n))
+#define gcmOPT_SetSplitVecMUL() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
+                                 gcmGetOptimizerOption()->splitVec4MUL = gcvTRUE)
+#define gcmOPT_SetSplitVecMULLO() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
+                                  gcmGetOptimizerOption()->splitVec4MULLO = gcvTRUE)
+#define gcmOPT_SetSplitVecDP3() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
+                                 gcmGetOptimizerOption()->splitVec4DP3 = gcvTRUE)
+#define gcmOPT_SetSplitVecDP4() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
+                                 gcmGetOptimizerOption()->splitVec4DP4 = gcvTRUE)
+#define gcmOPT_getFeatureBits(FBit)   (gcmGetOptimizerOption()->featureBits)
+#define gcmOPT_hasFeature(FBit)   ((gcmGetOptimizerOption()->featureBits & (FBit)) != 0)
+#define gcmOPT_SetFeature(FBit)   do { gcmGetOptimizerOption()->featureBits |= (FBit); } while (0)
+#define gcmOPT_ResetFeature(FBit) do { gcmGetOptimizerOption()->featureBits &= ~(FBit); } while (0)
+
+extern void gcOPT_SetFeature(gctUINT FBit);
+extern void gcOPT_ResetFeature(gctUINT FBit);
+
+#define gcmOPT_SetPackVarying(v)      (gcmGetOptimizerOption()->packVarying = v)
+
+#define gcmOPT_SetDual16PrecisionRule(v)     (gcmGetOptimizerOption()->dual16PrecisionRule = v)
+
+/* temporarily change PredefinedDummySamplerId from 7 to 8 */
+#define PredefinedDummySamplerId       8
+
+/* Function argument qualifier */
+typedef enum _gceINPUT_OUTPUT
+{
+    gcvFUNCTION_INPUT,
+    gcvFUNCTION_OUTPUT,
+    gcvFUNCTION_INOUT
+}
+gceINPUT_OUTPUT;
+
+typedef enum _gceVARIABLE_UPDATE_FLAGS
+{
+    gcvVARIABLE_UPDATE_NOUPDATE = 0,
+    gcvVARIABLE_UPDATE_TEMPREG,
+    gcvVARIABLE_UPDATE_TYPE_QUALIFIER,
+}gceVARIABLE_UPDATE_FLAGS;
+
+typedef enum _gcePROVOKING_VERTEX_CONVENSION
+{
+    gcvPROVOKING_VERTEX_FIRST = 0,
+    gcvPROVOKING_VERTEX_LAST,
+    gcvPROVOKING_VERTEX_UNDEFINE
+}
+gcePROVOKING_VERTEX_CONVENSION;
+
+#define __DEFAULT_GLSL_EXTENSION_STRING__       "GL_OES_texture_storage_multisample_2d_array "\
+                                                "GL_KHR_blend_equation_advanced "\
+                                                "GL_EXT_texture_buffer "\
+                                                "GL_EXT_texture_cube_map_array "\
+                                                "GL_EXT_shader_io_blocks "\
+                                                "GL_EXT_gpu_shader5 "\
+                                                "GL_EXT_geometry_shader "\
+                                                "GL_EXT_geometry_point_size "\
+                                                "GL_EXT_tessellation_shader "\
+                                                "GL_EXT_tessellation_point_size "\
+                                                "GL_OES_sample_variables "\
+                                                "GL_OES_shader_multisample_interpolation"
+
+typedef struct _gcsGLSLCaps
+{
+    gctUINT maxDrawBuffers;
+    gctUINT maxSamples;
+    gctUINT maxVertTextureImageUnits;
+    gctUINT maxCmptTextureImageUnits;
+    gctUINT maxFragTextureImageUnits;
+    gctUINT maxTcsTextureImageUnits;
+    gctUINT maxTesTextureImageUnits;
+    gctUINT maxGsTextureImageUnits;
+    gctUINT maxCombinedTextureImageUnits;
+    gctUINT maxTextureSamplers;
+    gctINT  minProgramTexelOffset;
+    gctINT  maxProgramTexelOffset;
+    gctINT  minProgramTexGatherOffset;
+    gctINT  maxProgramTexGatherOffset;
+
+    gctUINT maxVertAttributes;
+    gctUINT maxUserVertAttributes;
+    gctUINT maxVertStreams;
+    gctUINT maxBuildInVertAttributes;
+    gctUINT maxVaryingVectors;
+    gctUINT maxVertOutVectors;
+    gctUINT maxFragInVectors;
+    gctUINT maxTcsOutVectors;
+    gctUINT maxTcsOutPatchVectors;
+    gctUINT maxTcsOutTotalVectors;
+    gctUINT maxTesOutVectors;
+    gctUINT maxGsOutVectors;
+    gctUINT maxTcsInVectors;
+    gctUINT maxTesInVectors;
+    gctUINT maxGsInVectors;
+    gctUINT maxGsOutTotalVectors;
+
+    gctUINT maxVertUniformVectors;
+    gctUINT maxFragUniformVectors;
+    gctUINT maxCmptUniformVectors;
+    gctUINT maxTcsUniformVectors;
+    gctUINT maxTesUniformVectors;
+    gctUINT maxGsUniformVectors;
+    gctINT  maxUniformLocations;
+
+    /* buffer bindings */
+    gctUINT uniformBufferOffsetAlignment;
+    gctUINT maxUniformBufferBindings;
+    gctUINT maxVertUniformBlocks;
+    gctUINT maxFragUniformBlocks;
+    gctUINT maxCmptUniformBlocks;
+    gctUINT maxTcsUniformBlocks;
+    gctUINT maxTesUniformBlocks;
+    gctUINT maxGsUniformBlocks;
+    gctUINT maxCombinedUniformBlocks;
+    gctUINT64 maxUniformBlockSize;
+    gctUINT64 maxCombinedVertUniformComponents;
+    gctUINT64 maxCombinedFragUniformComponents;
+    gctUINT64 maxCombinedCmptUniformComponents;
+    gctUINT64 maxCombinedTcsUniformComponents;
+    gctUINT64 maxCombinedTesUniformComponents;
+    gctUINT64 maxCombinedGsUniformComponents;
+
+    gctUINT maxVertAtomicCounters;
+    gctUINT maxFragAtomicCounters;
+    gctUINT maxCmptAtomicCounters;
+    gctUINT maxTcsAtomicCounters;
+    gctUINT maxTesAtomicCounters;
+    gctUINT maxGsAtomicCounters;
+    gctUINT maxCombinedAtomicCounters;
+    gctUINT maxVertAtomicCounterBuffers;
+    gctUINT maxFragAtomicCounterBuffers;
+    gctUINT maxCmptAtomicCounterBuffers;
+    gctUINT maxTcsAtomicCounterBuffers;
+    gctUINT maxTesAtomicCounterBuffers;
+    gctUINT maxGsAtomicCounterBuffers;
+    gctUINT maxCombinedAtomicCounterBuffers;
+    gctUINT maxAtomicCounterBufferBindings;
+    gctUINT64 maxAtomicCounterBufferSize;
+
+    gctUINT shaderStorageBufferOffsetAlignment;
+    gctUINT maxVertShaderStorageBlocks;
+    gctUINT maxFragShaderStorageBlocks;
+    gctUINT maxCmptShaderStorageBlocks;
+    gctUINT maxTcsShaderStorageBlocks;
+    gctUINT maxTesShaderStorageBlocks;
+    gctUINT maxGsShaderStorageBlocks;
+    gctUINT maxCombinedShaderStorageBlocks;
+    gctUINT maxShaderStorageBufferBindings;
+    gctUINT64 maxShaderBlockSize;
+
+    gctUINT maxXfbInterleavedComponents;
+    gctUINT maxXfbSeparateComponents;
+    gctUINT maxXfbSeparateAttribs;
+    gctUINT maxXfbBuffers;
+
+    gctUINT maxProgErrStrLen;
+
+    /* Image limits  */
+    gctUINT maxVertexImageUniform;
+    gctUINT maxFragImageUniform;
+    gctUINT maxCmptImageUniform;
+    gctUINT maxTcsImageUniform;
+    gctUINT maxTesImageUniform;
+    gctUINT maxGsImageUniform;
+    gctUINT maxImageUnit;
+    gctUINT maxCombinedImageUniform;
+    gctUINT maxCombinedShaderOutputResource;
+
+    /* Compute limits */
+    gctUINT maxWorkGroupCount[3];
+    gctUINT maxWorkGroupSize[3];
+    gctUINT maxWorkGroupInvocation;
+    gctUINT maxShareMemorySize;
+
+    /* TS-only limits */
+    gctUINT maxTessPatchVertices;
+    gctUINT maxTessGenLevel;
+    gctBOOL tessPatchPR;
+
+    /* GS-only limits */
+    gctUINT maxGsOutVertices;
+    gcePROVOKING_VERTEX_CONVENSION provokingVertex;
+    gctUINT maxGsInvocationCount;
+
+    /* Desktop GL limits */
+    gctUINT maxClipDistances;
+    gctUINT maxClipPlanes;
+    gctUINT maxFragmentUniformComponents;
+    gctUINT maxTextureCoords;
+    gctUINT maxTextureUnits;
+    gctUINT maxVaryingComponents;
+    gctUINT maxVaryingFloats;
+    gctUINT maxVertexUniformComponents;
+    gctUINT maxFragmentInputComponents;
+    gctUINT maxVertexOutputComponents;
+    gctUINT maxGSVaryingComponents;
+
+    /* GLSL extension string. */
+    gctSTRING extensions;
+} gcsGLSLCaps;
+
+/* PatchID*/
+extern gcePATCH_ID gcPatchId;
+extern gcePATCH_ID *
+    gcGetPatchId(
+    void
+    );
+
+#define GetPatchID()                          (gcGetPatchId())
+
+/* HW caps.*/
+typedef struct _VSC_HW_CONFIG gcsHWCaps;
+extern gcsHWCaps gcHWCaps;
+extern gcsHWCaps *
+    gcGetHWCaps(
+    void
+    );
+
+/* Get HW features. */
+#define GetHWHasHalti0()                      (gcGetHWCaps()->hwFeatureFlags.hasHalti0)
+#define GetHWHasHalti1()                      (gcGetHWCaps()->hwFeatureFlags.hasHalti1)
+#define GetHWHasHalti2()                      (gcGetHWCaps()->hwFeatureFlags.hasHalti2)
+#define GetHWHasHalti5()                      (gcGetHWCaps()->hwFeatureFlags.hasHalti5)
+#define GetHWHasFmaSupport()                  (gcGetHWCaps()->hwFeatureFlags.supportAdvancedInsts)
+#define GetHWHasTS()                          (gcGetHWCaps()->hwFeatureFlags.supportTS)
+#define GetHWHasGS()                          (gcGetHWCaps()->hwFeatureFlags.supportGS)
+#define GetHWHasSamplerBaseOffset()           (gcGetHWCaps()->hwFeatureFlags.hasSamplerBaseOffset)
+#define GetHWHasUniversalTexldV2()            (gcGetHWCaps()->hwFeatureFlags.hasUniversalTexldV2)
+#define GetHWHasTexldUFix()                   (gcGetHWCaps()->hwFeatureFlags.hasTexldUFix)
+#define GetHWHasImageOutBoundaryFix()         (gcGetHWCaps()->hwFeatureFlags.hasImageOutBoundaryFix)
+
+/* Get HW caps. */
+#define GetHWVertexSamplerBase()              (gcGetHWCaps()->vsSamplerRegNoBase)
+#define GetHWFragmentSamplerBase()            (gcGetHWCaps()->psSamplerRegNoBase)
+
+#define GetHWInitWorkGroupSizeToCalcRegCount()(gcGetHWCaps()->initWorkGroupSizeToCalcRegCount)
+#define GetHWMaxWorkGroupSize()               (gcGetHWCaps()->maxWorkGroupSize)
+#define GetHWMinWorkGroupSize()               (gcGetHWCaps()->minWorkGroupSize)
+
+/* GLSL caps. */
+extern gcsGLSLCaps gcGLSLCaps;
+extern gcsGLSLCaps *
+    gcGetGLSLCaps(
+    void
+    );
+extern gceSTATUS gcInitGLSLCaps(
+    OUT gcsGLSLCaps *Caps
+    );
+
+#define GetGLMaxVertexAttribs()               (gcGetGLSLCaps()->maxUserVertAttributes)
+#define GetGLMaxVertexUniformVectors()        (gcGetGLSLCaps()->maxVertUniformVectors)
+#define GetGLMaxVertexOutputVectors()         (gcGetGLSLCaps()->maxVertOutVectors)
+#define GetGLMaxFragmentInputVectors()        (gcGetGLSLCaps()->maxFragInVectors)
+/* Texture Image. */
+#define GetGLMaxVertexTextureImageUnits()     (gcGetGLSLCaps()->maxVertTextureImageUnits)
+#define GetGLMaxCombinedTextureImageUnits()   (gcGetGLSLCaps()->maxCombinedTextureImageUnits)
+#define GetGLMaxFragTextureImageUnits()       (gcGetGLSLCaps()->maxFragTextureImageUnits)
+#define GetGLMaxFragmentUniformVectors()      (gcGetGLSLCaps()->maxFragUniformVectors)
+#define GetGLMaxDrawBuffers()                 (gcGetGLSLCaps()->maxDrawBuffers)
+#define GetGLMaxSamples()                     (gcGetGLSLCaps()->maxSamples)
+
+#define GetGLMaxUniformLocations()            (gcGetGLSLCaps()->maxUniformLocations)
+#define GetGLMinProgramTexelOffset()          (gcGetGLSLCaps()->minProgramTexelOffset)
+#define GetGLMaxProgramTexelOffset()          (gcGetGLSLCaps()->maxProgramTexelOffset)
+/* Image. */
+#define GetGLMaxImageUnits()                  (gcGetGLSLCaps()->maxImageUnit)
+#define GetGLMaxVertexImageUniforms()         (gcGetGLSLCaps()->maxVertexImageUniform)
+#define GetGLMaxFragmentImageUniforms()       (gcGetGLSLCaps()->maxFragImageUniform)
+#define GetGLMaxComputeImageUniforms()        (gcGetGLSLCaps()->maxCmptImageUniform)
+#define GetGLMaxCombinedImageUniforms()       (gcGetGLSLCaps()->maxCombinedImageUniform)
+#define GetGLMaxCombinedShaderOutputResources() (gcGetGLSLCaps()->maxCombinedShaderOutputResource)
+#define GetGLMaxComputeWorkGroupCount(Index)  (gcGetGLSLCaps()->maxWorkGroupCount[(Index)])
+#define GetGLMaxComputeWorkGroupSize(Index)   (gcGetGLSLCaps()->maxWorkGroupSize[(Index)])
+#define GetGLMaxWorkGroupInvocation()         (gcGetGLSLCaps()->maxWorkGroupInvocation)
+#define GetGLMaxSharedMemorySize()            (gcGetGLSLCaps()->maxShareMemorySize)
+#define GetGLMaxComputeUniformComponents()    (gcGetGLSLCaps()->maxCmptUniformVectors * 4)
+#define GetGLMaxComputeTextureImageUnits()    (gcGetGLSLCaps()->maxCmptTextureImageUnits)
+/* Atomic Counters. */
+#define GetGLMaxComputeAtomicCounters()       (gcGetGLSLCaps()->maxCmptAtomicCounters)
+#define GetGLMaxComputeAtomicCounterBuffers() (gcGetGLSLCaps()->maxCmptAtomicCounterBuffers)
+#define GetGLMaxVertexAtomicCounters()        (gcGetGLSLCaps()->maxVertAtomicCounters)
+#define GetGLMaxFragmentAtomicCounters()      (gcGetGLSLCaps()->maxFragAtomicCounters)
+#define GetGLMaxCombinedAtomicCounters()      (gcGetGLSLCaps()->maxCombinedAtomicCounters)
+#define GetGLMaxAtomicCounterBindings()       (gcGetGLSLCaps()->maxAtomicCounterBufferBindings)
+#define GetGLMaxVertexAtomicCounterBuffers()  (gcGetGLSLCaps()->maxVertAtomicCounterBuffers)
+#define GetGLMaxFragmentAtomicCounterBuffers()(gcGetGLSLCaps()->maxFragAtomicCounterBuffers)
+#define GetGLMaxCombinedAtomicCounterBuffers()(gcGetGLSLCaps()->maxCombinedAtomicCounterBuffers)
+#define GetGLMaxAtomicCounterBufferSize()     (gcGetGLSLCaps()->maxAtomicCounterBufferSize)
+#define GetGLMaxVaryingVectors()              (gcGetGLSLCaps()->maxVaryingVectors)
+/* Storage Buffer. */
+#define GetGLMaxVertexShaderStorageBufferBindings()     (gcGetGLSLCaps()->maxVertShaderStorageBlocks)
+#define GetGLMaxFragmentShaderStorageBufferBindings()   (gcGetGLSLCaps()->maxFragShaderStorageBlocks)
+#define GetGLMaxComputeShaderStorageBufferBindings()    (gcGetGLSLCaps()->maxCmptShaderStorageBlocks)
+#define GetGLMaxShaderStorageBufferBindings()           (gcGetGLSLCaps()->maxShaderStorageBufferBindings)
+/* Uniform Buffer. */
+#define GetGLMaxVertexUniformBufferBindings()           (gcGetGLSLCaps()->maxVertUniformBlocks)
+#define GetGLMaxFragmentUniformBufferBindings()         (gcGetGLSLCaps()->maxFragUniformBlocks)
+#define GetGLMaxComputeUniformBufferBindings()          (gcGetGLSLCaps()->maxCmptUniformBlocks)
+#define GetGLMaxCombinedUniformBufferBindings()         (gcGetGLSLCaps()->maxUniformBufferBindings)
+#define GetGLMaxUniformBLockSize()            (gcGetGLSLCaps()->maxUniformBlockSize)
+
+/* TS constants */
+#define GetGLMaxTCSTextureImageUnits()        (gcGetGLSLCaps()->maxTcsTextureImageUnits)
+#define GetGLMaxTCSUniformVectors()           (gcGetGLSLCaps()->maxTcsUniformVectors)
+#define GetGLMaxTCSOutTotalVectors()          (gcGetGLSLCaps()->maxTcsOutTotalVectors)
+#define GetGLMaxTCSInputVectors()             (gcGetGLSLCaps()->maxTcsInVectors)
+#define GetGLMaxTCSOutputVectors()            (gcGetGLSLCaps()->maxTcsOutVectors)
+#define GetGLMaxTCSAtomicCounters()           (gcGetGLSLCaps()->maxTcsAtomicCounters)
+#define GetGLMaxTCSAtomicCounterBuffers()     (gcGetGLSLCaps()->maxTcsAtomicCounterBuffers)
+#define GetGLMaxTCSImageUniforms()            (gcGetGLSLCaps()->maxTcsImageUniform)
+#define GetGLMaxTCSUniformBufferBindings()    (gcGetGLSLCaps()->maxTcsUniformBlocks)
+#define GetGLMaxTCSShaderStorageBufferBindings()     (gcGetGLSLCaps()->maxTcsShaderStorageBlocks)
+
+#define GetGLMaxTESTextureImageUnits()        (gcGetGLSLCaps()->maxTesTextureImageUnits)
+#define GetGLMaxTESUniformVectors()           (gcGetGLSLCaps()->maxTesUniformVectors)
+#define GetGLMaxTESOutTotalVectors()          (gcGetGLSLCaps()->maxTesOutTotalVectors)
+#define GetGLMaxTESInputVectors()             (gcGetGLSLCaps()->maxTesInVectors)
+#define GetGLMaxTESOutputVectors()            (gcGetGLSLCaps()->maxTesOutVectors)
+#define GetGLMaxTESAtomicCounters()           (gcGetGLSLCaps()->maxTesAtomicCounters)
+#define GetGLMaxTESAtomicCounterBuffers()     (gcGetGLSLCaps()->maxTesAtomicCounterBuffers)
+#define GetGLMaxTESImageUniforms()            (gcGetGLSLCaps()->maxTesImageUniform)
+#define GetGLMaxTESUniformBufferBindings()    (gcGetGLSLCaps()->maxTesUniformBlocks)
+#define GetGLMaxTESShaderStorageBufferBindings()     (gcGetGLSLCaps()->maxTesShaderStorageBlocks)
+
+#define GetGLMaxTessPatchVertices()           (gcGetGLSLCaps()->maxTessPatchVertices)
+#define GetGLMaxTessGenLevel()                (gcGetGLSLCaps()->maxTessGenLevel)
+#define GetGLMaxTessPatchVectors()            (gcGetGLSLCaps()->maxTcsOutPatchVectors)
+
+/* GS constants. */
+#define GetGLMaxGSTextureImageUnits()         (gcGetGLSLCaps()->maxGsTextureImageUnits)
+#define GetGLMaxGSOutVectors()                (gcGetGLSLCaps()->maxGsOutVectors)
+#define GetGLMaxGSInVectors()                 (gcGetGLSLCaps()->maxGsInVectors)
+#define GetGLMaxGSOutTotalVectors()           (gcGetGLSLCaps()->maxGsOutTotalVectors)
+#define GetGLMaxGSUniformVectors()            (gcGetGLSLCaps()->maxGsUniformVectors)
+#define GetGLMaxGSUniformBlocks()             (gcGetGLSLCaps()->maxGsUniformBlocks)
+#define GetGLMaxGSAtomicCounters()            (gcGetGLSLCaps()->maxGsAtomicCounters)
+#define GetGLMaxGSAtomicCounterBuffers()      (gcGetGLSLCaps()->maxGsAtomicCounterBuffers)
+#define GetGLMaxGSImageUniforms()             (gcGetGLSLCaps()->maxGsImageUniform)
+#define GetGLMaxGSOutVertices()               (gcGetGLSLCaps()->maxGsOutVertices)
+#define GetGLMaxGSInvocationCount()           (gcGetGLSLCaps()->maxGsInvocationCount)
+#define GetGLMaxGSUniformBufferBindings()     (gcGetGLSLCaps()->maxGsUniformBlocks)
+#define GetGLMaxGSShaderStorageBufferBindings()     (gcGetGLSLCaps()->maxGsShaderStorageBlocks)
+
+/* Desktop GL constants */
+#define GetGLMaxClipDistances()               (gcGetGLSLCaps()->maxClipDistances)
+#define GetGLMaxClipPlanes()                  (gcGetGLSLCaps()->maxClipPlanes)
+#define GetGLMaxFragmentUniformComponents()   (gcGetGLSLCaps()->maxFragmentUniformComponents)
+#define GetGLMaxTextureCoords()               (gcGetGLSLCaps()->maxTextureCoords)
+#define GetGLMaxTextureUnits()                (gcGetGLSLCaps()->maxTextureUnits)
+#define GetGLMaxVaryingComponents()           (gcGetGLSLCaps()->maxVaryingComponents)
+#define GetGLMaxVaryingFloats()               (gcGetGLSLCaps()->maxVaryingFloats)
+#define GetGLMaxVertexUniformComponents()     (gcGetGLSLCaps()->maxVertexUniformComponents)
+#define GetGLMaxFragmentInputComponents()     (gcGetGLSLCaps()->maxFragmentInputComponents)
+#define GetGLMaxVertexOutputComponents()      (gcGetGLSLCaps()->maxVertexOutputComponents)
+#define GetGLMaxGSVaryingComponents()         (gcGetGLSLCaps()->maxGSVaryingComponents)
+
+/* GLSL extension string. */
+#define GetGLExtensionString()                (gcGetGLSLCaps()->extensions)
+
+void
+gcGetOptionFromEnv(
+    IN OUT gcOPTIMIZER_OPTION * Option
+    );
+
+void
+gcSetOptimizerOption(
+    IN gceSHADER_FLAGS Flags
+    );
+
+gcOPTIMIZER_OPTION *
+gcGetOptimizerOption(void);
+
+gcOPTIMIZER_OPTION *
+gcGetOptimizerOptionVariable(void);
+
+gctBOOL
+gcUseFullNewLinker(gctBOOL HasHalti2);
+
+typedef gceSTATUS (*gctGLSLCompiler)(IN  gctINT ShaderType,
+                                     IN  gctUINT SourceSize,
+                                     IN  gctCONST_STRING Source,
+                                     OUT gcSHADER *Binary,
+                                     OUT gctSTRING *Log);
+
+typedef gceSTATUS (*gctGLSLInitCompiler)(IN gcePATCH_ID PatchId,
+                                         IN gcsHWCaps *HWCaps,
+                                         IN gcsGLSLCaps *Caps);
+
+typedef gceSTATUS (*gctGLSLInitCompilerCaps)(IN gcsGLSLCaps *Caps);
+
+typedef gceSTATUS (*gctGLSLFinalizeCompiler)(void);
+
+void
+gcSetGLSLCompiler(
+    IN gctGLSLCompiler Compiler
+    );
+
+typedef gceSTATUS (*gctCLCompiler)(IN  gcoHAL Hal,
+                                       IN  gctUINT SourceSize,
+                                       IN  gctCONST_STRING Source,
+                                       IN  gctCONST_STRING Option,
+                                       OUT gcSHADER *Binary,
+                                       OUT gctSTRING *Log);
+
+void
+gcSetCLCompiler(
+    IN gctCLCompiler Compiler
+    );
+
+extern gcsGLSLCaps *gcGetGLSLcap(void);
+
+/*******************************************************************************
+**  gcSHADER_SetDefaultUBO
+**
+**  Set the compiler enable/disable default UBO.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to gcSHADER object
+**
+**      gctBOOL Enabled
+**          Pointer to enable/disable default UBO
+*/
+gceSTATUS
+gcSHADER_SetDefaultUBO(
+    IN gcSHADER Shader,
+    IN gctBOOL Enabled
+    );
+
+/*******************************************************************************
+**  gcSHADER_SetCompilerVersion
+**
+**  Set the compiler version of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to gcSHADER object
+**
+**      gctINT *Version
+**          Pointer to a two word version
+*/
+gceSTATUS
+gcSHADER_SetCompilerVersion(
+    IN gcSHADER Shader,
+    IN gctUINT32 *Version
+    );
+
+/*******************************************************************************
+**  gcSHADER_SetClientApiVersion
+**
+**  Set the client API version of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gceAPI API
+**          Client API version.
+*/
+gceSTATUS
+gcSHADER_SetClientApiVersion(
+    IN gcSHADER Shader,
+    IN gceAPI Api
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetCompilerVersion
+**
+**  Get the compiler version of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32_PTR *CompilerVersion.
+**          Pointer to holder of returned compilerVersion pointer
+*/
+gceSTATUS
+gcSHADER_GetCompilerVersion(
+    IN gcSHADER Shader,
+    OUT gctUINT32_PTR *CompilerVersion
+    );
+
+gctBOOL
+gcSHADER_IsESCompiler(
+    IN gcSHADER Shader
+    );
+
+gctBOOL
+gcSHADER_IsES11Compiler(
+    IN gcSHADER Shader
+    );
+
+gctBOOL
+gcSHADER_IsES30Compiler(
+    IN gcSHADER Shader
+    );
+
+gctBOOL
+gcSHADER_IsES31Compiler(
+    IN gcSHADER Shader
+    );
+
+gctBOOL
+gcSHADER_IsES32Compiler(
+    IN gcSHADER Shader
+    );
+
+gctBOOL
+gcSHADER_IsHaltiCompiler(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**  gcSHADER_IsOGLCompiler
+**
+**  Check if the shader is OGL shader.
+**  Note: should use this API instead of VIR_Shader_IsDesktopGL() to do this check,
+**        because detecting by clientApiVersion does not work in some cases.
+**
+*/
+
+gctBOOL
+gcSHADER_IsOGLCompiler(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**  gcSHADER_SetShaderID
+**
+**  Set a unique id for this shader base on shader source string.
+**
+**  INPUT:
+**
+**      gcSHADER  Shader
+**          Pointer to an shader object.
+**
+**      gctUINT32 ID
+**          The value of shader id.
+*/
+gceSTATUS
+gcSHADER_SetShaderID(
+    IN gcSHADER  Shader,
+    IN gctUINT32 ID
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetShaderID
+**
+**  Get the unique id of this shader.
+**
+**  INPUT:
+**
+**      gcSHADER  Shader
+**          Pointer to an shader object.
+**
+**      gctUINT32 * ID
+**          The value of shader id.
+*/
+gceSTATUS
+gcSHADER_GetShaderID(
+    IN gcSHADER  Shader,
+    IN gctUINT32 * ID
+    );
+
+/*******************************************************************************
+**  gcSHADER_SetDisableEZ
+**
+**  Set disable EZ for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER  Shader
+**          Pointer to an shader object.
+**
+**      gctBOOL Disabled
+**          Disable or not.
+*/
+gceSTATUS
+gcSHADER_SetDisableEZ(
+    IN gcSHADER  Shader,
+    IN gctBOOL Disabled
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetDisableEZ
+**
+**  Get disable EZ of this shader.
+**
+**  INPUT:
+**
+**      gcSHADER  Shader
+**          Pointer to an shader object.
+**
+**      gctBOOL * Disabled
+**          The value of Disable EZ.
+*/
+gceSTATUS
+gcSHADER_GetDisableEZ(
+    IN gcSHADER  Shader,
+    IN gctBOOL * Disabled
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetType
+**
+**  Get the gcSHADER object's type.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctINT *Type.
+**          Pointer to return shader type.
+*/
+gceSTATUS
+gcSHADER_GetType(
+    IN gcSHADER Shader,
+    OUT gcSHADER_KIND *Type
+    );
+
+gctUINT
+gcSHADER_NextId(void);
+
+void
+gcSHADER_AlignId(void);
+/*******************************************************************************
+**                             gcSHADER_Construct
+********************************************************************************
+**
+**    Construct a new gcSHADER object.
+**
+**    INPUT:
+**
+**        gcoOS Hal
+**            Pointer to an gcoHAL object.
+**
+**        gctINT ShaderType
+**            Type of gcSHADER object to cerate.  'ShaderType' can be one of the
+**            following:
+**
+**                gcSHADER_TYPE_VERTEX    Vertex shader.
+**                gcSHADER_TYPE_FRAGMENT    Fragment shader.
+**
+**    OUTPUT:
+**
+**        gcSHADER * Shader
+**            Pointer to a variable receiving the gcSHADER object pointer.
+*/
+gceSTATUS
+gcSHADER_Construct(
+    IN gctINT ShaderType,
+    OUT gcSHADER * Shader
+    );
+
+/*******************************************************************************
+**                              gcSHADER_Destroy
+********************************************************************************
+**
+**    Destroy a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_Destroy(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**                              gcSHADER_Copy
+********************************************************************************
+**
+**    Copy a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**      gcSHADER Source
+**          Pointer to a gcSHADER object that will be copied.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_Copy(
+    IN gcSHADER Shader,
+    IN gcSHADER Source
+    );
+
+/*******************************************************************************
+**  gcSHADER_LoadHeader
+**
+**  Load a gcSHADER object from a binary buffer.  The binary buffer is layed out
+**  as follows:
+**      // Six word header
+**      // Signature, must be 'S','H','D','R'.
+**      gctINT8             signature[4];
+**      gctUINT32           binFileVersion;
+**      gctUINT32           compilerVersion[2];
+**      gctUINT32           gcSLVersion;
+**      gctUINT32           binarySize;
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**          Shader type will be returned if type in shader object is not gcSHADER_TYPE_PRECOMPILED
+**
+**      gctPOINTER Buffer
+**          Pointer to a binary buffer containing the shader data to load.
+**
+**      gctUINT32 BufferSize
+**          Number of bytes inside the binary buffer pointed to by 'Buffer'.
+**
+**  OUTPUT:
+**      nothing
+**
+*/
+gceSTATUS
+gcSHADER_LoadHeader(
+    IN gcSHADER Shader,
+    IN gctPOINTER Buffer,
+    IN gctUINT32 BufferSize,
+    OUT gctUINT32 * ShaderVersion
+    );
+
+/*******************************************************************************
+**  gcSHADER_LoadKernel
+**
+**  Load a kernel function given by name into gcSHADER object
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctSTRING KernelName
+**          Pointer to a kernel function name
+**
+**  OUTPUT:
+**      nothing
+**
+*/
+gceSTATUS
+gcSHADER_LoadKernel(
+    IN gcSHADER Shader,
+    IN gctSTRING KernelName
+    );
+
+/*     Remove unused register.
+ */
+gceSTATUS
+gcSHADER_PackRegister(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**                                gcMergeKernel
+********************************************************************************
+**
+**    Merge a list of OpenCL kernel binaries and form a single consistent kernel
+**    binary as if the original kernel source corresponding to each kernel binary
+**    were concatenated together into one source and then compiled to create the
+**    kernel binary.
+**
+**    INPUT:
+**        gctINT KernelCount
+**            number of gcSHADER object in the shader array
+**
+**        gcSHADER *KernelArray
+**            Array of gcSHADER object holding information about the compiled
+**            openCL kernel.
+**
+**    OUTPUT:
+**
+**        gcSHADER * MergedKernel
+**            Pointer to a variable receiving the handle to the merged kernel
+**
+*/
+gceSTATUS
+gcSHADER_MergeKernel(
+    IN gctINT         KernelCount,
+    IN gcSHADER *     KernelArray,
+    OUT gcSHADER *    MergedKernel
+    );
+
+/*******************************************************************************
+**                                gcMergeShader
+********************************************************************************
+**
+**    Merge a list of OpenGL shader binaries and form a single consistent shader
+**    binary
+**
+**    INPUT:
+**        gctINT ShaderCount
+**            number of gcSHADER object in the shader array
+**
+**        gcSHADER *ShaderArray
+**            Array of gcSHADER object holding information about the compiled
+**            openGL shader.
+**
+**    OUTPUT:
+**
+**        gcSHADER * MergedShader
+**            Pointer to a variable receiving the handle to the merged shader
+**
+*/
+gceSTATUS
+gcSHADER_MergeShader(
+    IN gctINT         ShaderCount,
+    IN gcSHADER *     ShaderArray,
+    OUT gcSHADER *    MergedShader
+    );
+
+/*******************************************************************************
+**                                gcSHADER_Load
+********************************************************************************
+**
+**    Load a gcSHADER object from a binary buffer.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctPOINTER Buffer
+**            Pointer to a binary buffer containg the shader data to load.
+**
+**        gctUINT32 BufferSize
+**            Number of bytes inside the binary buffer pointed to by 'Buffer'.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_Load(
+    IN gcSHADER Shader,
+    IN gctPOINTER Buffer,
+    IN gctUINT32 BufferSize
+    );
+
+/*******************************************************************************
+**                                gcSHADER_Save
+********************************************************************************
+**
+**    Save a gcSHADER object to a binary buffer.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctPOINTER Buffer
+**            Pointer to a binary buffer to be used as storage for the gcSHADER
+**            object.  If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
+**            but the number of bytes required to hold the binary output for the
+**            gcSHADER object will be returned.
+**
+**        gctUINT32 * BufferSize
+**            Pointer to a variable holding the number of bytes allocated in
+**            'Buffer'.  Only valid if 'Buffer' is not gcvNULL.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * BufferSize
+**            Pointer to a variable receiving the number of bytes required to hold
+**            the binary form of the gcSHADER object.
+*/
+gceSTATUS
+gcSHADER_Save(
+    IN gcSHADER Shader,
+    IN gctPOINTER Buffer,
+    IN OUT gctUINT32 * BufferSize
+    );
+
+/*******************************************************************************
+**                                gcSHADER_LoadEx
+********************************************************************************
+**
+**    Load a gcSHADER object from a binary buffer.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctPOINTER Buffer
+**            Pointer to a binary buffer containg the shader data to load.
+**
+**        gctUINT32 BufferSize
+**            Number of bytes inside the binary buffer pointed to by 'Buffer'.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_LoadEx(
+    IN gcSHADER Shader,
+    IN gctPOINTER Buffer,
+    IN gctUINT32 BufferSize
+    );
+
+/*******************************************************************************
+**                                gcSHADER_SaveEx
+********************************************************************************
+**
+**    Save a gcSHADER object to a binary buffer.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctPOINTER Buffer
+**            Pointer to a binary buffer to be used as storage for the gcSHADER
+**            object.  If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
+**            but the number of bytes required to hold the binary output for the
+**            gcSHADER object will be returned.
+**
+**        gctUINT32 * BufferSize
+**            Pointer to a variable holding the number of bytes allocated in
+**            'Buffer'.  Only valid if 'Buffer' is not gcvNULL.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * BufferSize
+**            Pointer to a variable receiving the number of bytes required to hold
+**            the binary form of the gcSHADER object.
+*/
+gceSTATUS
+gcSHADER_SaveEx(
+    IN gcSHADER Shader,
+    IN gctPOINTER Buffer,
+    IN OUT gctUINT32 * BufferSize
+    );
+
+gceSTATUS
+gcSHADER_LinkBuiltinLibs(
+    IN gcSHADER* Shaders
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetLocationCount
+**
+**  Get the number of input/output locations for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of locations.
+*/
+gceSTATUS
+gcSHADER_GetLocationCount(
+    IN gcSHADER Shader,
+    IN gctBOOL Input,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetLocation
+**
+**  Get the location assocated with an indexed input/output for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT Index
+**          Index of input/output to retreive the location setting for.
+**
+**  OUTPUT:
+**
+**      gctINT * Location
+**          Pointer to a variable receiving the location value.
+*/
+gceSTATUS
+gcSHADER_GetLocation(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    IN gctBOOL Input,
+    OUT gctINT * Location
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetBuiltinNameKind
+**
+**  Get the builtin name kind for the Name.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctCONST_STRING Name
+**          String of the name.
+**
+**  OUTPUT:
+**
+**      gceBuiltinNameKind * Kind
+**          Pointer to a variable receiving the builtin name kind value.
+*/
+gceSTATUS
+gcSHADER_GetBuiltinNameKind(
+    IN gcSHADER              Shader,
+    IN gctCONST_STRING       Name,
+    OUT gctUINT32 *          Kind
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetBuiltinNameString
+**
+**  Get the builtin name corresponding to its kind.
+**
+**  INPUT:
+**
+**      gctUINT32 Kind
+**          Builtin name kind.
+**
+**  RETURN:
+**
+**      gctCONST_STRING
+**          Pointer to the builtin name string.
+*/
+gctCONST_STRING
+gcSHADER_GetBuiltinNameString(
+    IN gctINT Kind
+    );
+
+/*******************************************************************************
+**  gcSHADER_ReallocateAttributes
+**
+**  Reallocate an array of pointers to gcATTRIBUTE objects.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcSHADER_ReallocateAttributes(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count
+    );
+
+/*******************************************************************************
+**                              gcSHADER_AddAttribute
+********************************************************************************
+**
+**    Add an attribute to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the attribute to add.
+**
+**        gcSHADER_TYPE Type
+**            Type of the attribute to add.
+**
+**        gctUINT32 Length
+**            Array length of the attribute to add.  'Length' must be at least 1.
+**
+**        gctBOOL IsTexture
+**            gcvTRUE if the attribute is used as a texture coordinate, gcvFALSE if not.
+**
+**    OUTPUT:
+**
+**        gcATTRIBUTE * Attribute
+**            Pointer to a variable receiving the gcATTRIBUTE object pointer.
+*/
+gceSTATUS
+gcSHADER_AddAttribute(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gctUINT32 Length,
+    IN gctBOOL IsTexture,
+    IN gcSHADER_SHADERMODE ShaderMode,
+    IN gcSHADER_PRECISION Precision,
+    OUT gcATTRIBUTE * Attribute
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddAttributeWithLocation
+**
+**  Add an attribute together with a location to a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctCONST_STRING Name
+**          Name of the attribute to add.
+**
+**      gcSHADER_TYPE Type
+**          Type of the attribute to add.
+**
+**      gcSHADER_PRECISION Precision,
+**          Precision of the attribute to add.
+**
+**      gctUINT32 Length
+**          Array length of the attribute to add.  'Length' must be at least 1.
+**
+**      gctBOOL IsTexture
+**          gcvTRUE if the attribute is used as a texture coordinate, gcvFALSE if not.
+**
+**      gctINT Location
+**          Location associated with the attribute.
+**
+**  OUTPUT:
+**
+**      gcATTRIBUTE * Attribute
+**          Pointer to a variable receiving the gcATTRIBUTE object pointer.
+*/
+gceSTATUS
+gcSHADER_AddAttributeWithLocation(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gcSHADER_PRECISION Precision,
+    IN gctUINT32 Length,
+    IN gctUINT32 ArrayLengthCount,
+    IN gctBOOL IsTexture,
+    IN gcSHADER_SHADERMODE ShaderMode,
+    IN gctINT Location,
+    IN gctINT FieldIndex,
+    IN gctBOOL IsInvariant,
+    IN gctBOOL IsPrecise,
+    OUT gcATTRIBUTE * Attribute
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetVertexInstIDInputIndex
+**
+**  Get the input index of vertex/instance ID for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+*/
+gctINT
+gcSHADER_GetVertexInstIdInputIndex(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**                         gcSHADER_GetAttributeCount
+********************************************************************************
+**
+**    Get the number of attributes for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Count
+**            Pointer to a variable receiving the number of attributes.
+*/
+gceSTATUS
+gcSHADER_GetAttributeCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetAttributeAndBuiltinInputCount
+**
+**  Get the number of attributes including builtin inputs for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of attributes including builtin inputs.
+*/
+gceSTATUS
+gcSHADER_GetAttributeAndBuiltinInputCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**                            gcSHADER_GetAttribute
+********************************************************************************
+**
+**    Get the gcATTRIBUTE object poniter for an indexed attribute for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT Index
+**            Index of the attribute to retrieve.
+**
+**    OUTPUT:
+**
+**        gcATTRIBUTE * Attribute
+**            Pointer to a variable receiving the gcATTRIBUTE object pointer.
+*/
+gceSTATUS
+gcSHADER_GetAttribute(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcATTRIBUTE * Attribute
+    );
+
+/*******************************************************************************
+**                            gcSHADER_GetAttributeByName
+********************************************************************************
+**
+**    Get the gcATTRIBUTE object poniter for an name attribute for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctSTRING name
+**            Name of output to retrieve.
+**
+**        gctUINT32 nameLength
+**            Length of name to retrieve
+**
+**    OUTPUT:
+**
+**        gcATTRIBUTE * Attribute
+**            Pointer to a variable receiving the gcATTRIBUTE object pointer.
+*/
+gceSTATUS
+gcSHADER_GetAttributeByName(
+    IN gcSHADER Shader,
+    IN gctSTRING Name,
+    IN gctUINT32 NameLength,
+    OUT gcATTRIBUTE * Attribute
+    );
+
+/*******************************************************************************
+**  gcSHADER_ReallocateUniforms
+**
+**  Reallocate an array of pointers to gcUNIFORM objects.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcSHADER_ReallocateUniforms(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count
+    );
+
+/* find the uniform with Name in the Shader,
+ * if found, return it in *Uniform
+ * otherwise add the uniform to shader
+ */
+gceSTATUS
+gcSHADER_FindAddUniform(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gctUINT32 Length,
+    IN gcSHADER_PRECISION Precision,
+    OUT gcUNIFORM * Uniform
+    );
+
+/*******************************************************************************
+**                               gcSHADER_AddUniform
+********************************************************************************
+**
+**    Add an uniform to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the uniform to add.
+**
+**        gcSHADER_TYPE Type
+**            Type of the uniform to add.
+**
+**        gctUINT32 Length
+**            Array length of the uniform to add.  'Length' must be at least 1.
+**
+**    OUTPUT:
+**
+**        gcUNIFORM * Uniform
+**            Pointer to a variable receiving the gcUNIFORM object pointer.
+*/
+gceSTATUS
+gcSHADER_AddUniform(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gctUINT32 Length,
+    IN gcSHADER_PRECISION Precision,
+    OUT gcUNIFORM * Uniform
+    );
+
+
+/*******************************************************************************
+**                               gcSHADER_AddUniformEx
+********************************************************************************
+**
+**    Add an uniform to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the uniform to add.
+**
+**        gcSHADER_TYPE Type
+**            Type of the uniform to add.
+**
+**      gcSHADER_PRECISION precision
+**          Precision of the uniform to add.
+**
+**        gctUINT32 Length
+**            Array length of the uniform to add.  'Length' must be at least 1.
+**
+**    OUTPUT:
+**
+**        gcUNIFORM * Uniform
+**            Pointer to a variable receiving the gcUNIFORM object pointer.
+*/
+gceSTATUS
+gcSHADER_AddUniformEx(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gcSHADER_PRECISION precision,
+    IN gctUINT32 Length,
+    OUT gcUNIFORM * Uniform
+    );
+
+/*******************************************************************************
+**                               gcSHADER_AddUniformEx1
+********************************************************************************
+**
+**    Add an uniform to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the uniform to add.
+**
+**        gcSHADER_TYPE Type
+**            Type of the uniform to add.
+**
+**      gcSHADER_PRECISION precision
+**          Precision of the uniform to add.
+**
+**        gctUINT32 Length
+**            Array length of the uniform to add.  'Length' must be at least 1.
+**
+**      gcSHADER_VAR_CATEGORY varCategory
+**          Variable category, normal or struct.
+**
+**      gctUINT16 numStructureElement
+**          If struct, its element number.
+**
+**      gctINT16 parent
+**          If struct, parent index in gcSHADER.variables.
+**
+**      gctINT16 prevSibling
+**          If struct, previous sibling index in gcSHADER.variables.
+**
+**      gctINT16 imageFormat
+**          image format for the uniform to add
+**
+**    OUTPUT:
+**
+**        gcUNIFORM * Uniform
+**            Pointer to a variable receiving the gcUNIFORM object pointer.
+**
+**      gctINT16* ThisUniformIndex
+**          Returned value about uniform index in gcSHADER.
+*/
+gceSTATUS
+gcSHADER_AddUniformEx1(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gcSHADER_PRECISION precision,
+    IN gctINT32 location,
+    IN gctINT32 binding,
+    IN gctINT32 bindingOffset,
+    IN gctINT ArrayLengthCount,
+    IN gctINT * ArrayLengthList,
+    IN gcSHADER_VAR_CATEGORY varCategory,
+    IN gctUINT16 numStructureElement,
+    IN gctINT16 parent,
+    IN gctINT16 prevSibling,
+    IN gctINT16 imageFormat,
+    OUT gctINT16* ThisUniformIndex,
+    OUT gcUNIFORM * Uniform
+    );
+
+/* create uniform for the constant vector and initialize it with Value */
+gceSTATUS
+gcSHADER_CreateConstantUniform(
+    IN gcSHADER                  Shader,
+    IN gcSHADER_TYPE             Type,
+    IN gcsValue *                Value,
+    OUT gcUNIFORM *              Uniform
+    );
+
+/* add uniform with compile-time initializer */
+gceSTATUS
+gcSHADER_AddUniformWithInitializer(
+    IN gcSHADER                  Shader,
+    IN gctCONST_STRING           Name,
+    IN gcSHADER_TYPE             Type,
+    IN gctUINT32                 Length,
+    IN gcSHADER_PRECISION        Precision,
+    IN gcsValue *                Value,
+    OUT gcUNIFORM *              Uniform
+    );
+
+gcSL_FORMAT
+gcGetFormatFromType(
+    IN gcSHADER_TYPE Type
+    );
+
+/*******************************************************************************
+**                          gcSHADER_GetUniformCount
+********************************************************************************
+**
+**    Get the number of uniforms for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Count
+**            Pointer to a variable receiving the number of uniforms.
+*/
+gceSTATUS
+gcSHADER_GetUniformCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**                          gcSHADER_GetSamplerCount
+********************************************************************************
+**
+**    Get the number of samplers for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Count
+**            Pointer to a variable receiving the number of samplers.
+*/
+gceSTATUS
+gcSHADER_GetSamplerCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**                          gcSHADER_GetKernelUniformCount
+********************************************************************************
+**
+**    Get the number of kernel uniforms for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Count
+**            Pointer to a variable receiving the number of uniforms.
+*/
+gceSTATUS
+gcSHADER_GetKernelUniformCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**                          gcSHADER_GetKernelOriginalUniformCount
+********************************************************************************
+**
+**    Get the number of kernel original uniforms for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Count
+**            Pointer to a variable receiving the number of original uniforms.
+*/
+gceSTATUS
+gcSHADER_GetKernelOriginalUniformCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformVectorCountByCategory
+**
+**  Get the number of vectors used by uniforms for this shader according to variable
+**  category.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSHADER_VAR_CATEGORY Category
+**          Category of uniform.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of vectors.
+*/
+gceSTATUS
+gcSHADER_GetUniformVectorCountByCategory(
+    IN gcSHADER Shader,
+    IN gcSHADER_VAR_CATEGORY Category,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformVectorCount
+**
+**  Get the number of vectors used by uniforms for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of vectors.
+*/
+gceSTATUS
+gcSHADER_GetUniformVectorCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformVectorCountUsedInShader
+**
+**  Get the number of vectors used by uniforms for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of vectors.
+*/
+gceSTATUS
+gcSHADER_GetUniformVectorCountUsedInShader(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformBlockCount
+**
+**  Get the number of uniform blocks for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of uniform blocks.
+*/
+gceSTATUS
+gcSHADER_GetUniformBlockCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformBlockCountUsedInShader
+**
+**  Get the number of uniform blocks for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of uniform blocks.
+*/
+gceSTATUS
+gcSHADER_GetUniformBlockCountUsedInShader(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformBlockUniformCount
+**
+**  Get the number of uniforms in a uniform block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcsUNIFORM_BLOCK UniformBlock
+**          Pointer to uniform block to retreive the uniform count.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of uniforms.
+*/
+gceSTATUS
+gcSHADER_GetUniformBlockUniformCount(
+    IN gcSHADER Shader,
+    gcsUNIFORM_BLOCK UniformBlock,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetStorageBlockVariableCount
+**
+**  Get the number of variables in a storage block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcsSTORAGE_BLOCK StorageBlock
+**          Pointer to storage block to retreive the variable count.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of variables in block.
+*/
+gceSTATUS
+gcSHADER_GetStorageBlockVariableCount(
+    IN gcSHADER Shader,
+    gcsSTORAGE_BLOCK StorageBlock,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_SetStorageBlockTopLevelMemberArrayInfo
+**
+**  Set the top level member array info (size, stride) of a storage block
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctINT VariableIndex
+**          Index to variable in the storage block
+**
+**      gctINT TopMember
+**          Flag indicating that variable is top level
+**
+**      gctINT ArraySize
+**          Top level array size to be used on non top level variable
+**
+**      gctINT ArrayStride
+**          Top level array stride to be used on non top level variable
+**
+*/
+gceSTATUS
+gcSHADER_SetStorageBlockTopLevelMemberArrayInfo(
+    IN gcSHADER Shader,
+    IN gctINT  VariableIndex,
+    IN gctBOOL TopMember,
+    IN gctINT ArraySize,
+    IN gctINT ArrayStride
+    );
+
+/*******************************************************************************
+**                             gcSHADER_GetUniform
+********************************************************************************
+**
+**    Get the gcUNIFORM object pointer for an indexed uniform for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT Index
+**            Index of the uniform to retrieve.
+**
+**    OUTPUT:
+**
+**        gcUNIFORM * Uniform
+**            Pointer to a variable receiving the gcUNIFORM object pointer.
+*/
+gceSTATUS
+gcSHADER_GetUniform(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcUNIFORM * Uniform
+    );
+
+/*******************************************************************************
+**                             gcSHADER_GetUniformByUniformIndex
+********************************************************************************
+**
+**    Get the gcUNIFORM object pointer for an indexed uniform itseft.
+**    For a OCL shader, if it has loaded a specified a uniform,
+**    the index in gcUNIFORM is not the same as the index in gcSHADER->uniforms,
+**    so we can't get the uniform by using gcSHADER->uniforms[index].
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT16 Index
+**            Index of the uniform to retrieve.
+**
+**    OUTPUT:
+**
+**        gcUNIFORM * Uniform
+**            Pointer to a variable receiving the gcUNIFORM object pointer.
+*/
+gceSTATUS
+gcSHADER_GetUniformByUniformIndex(
+    IN gcSHADER Shader,
+    IN gctUINT16 Index,
+    OUT gcUNIFORM * Uniform
+    );
+
+gceSTATUS
+gcSHADER_GetUniformByName(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING UniformName,
+    IN gctUINT32 NameLength,
+    OUT gcUNIFORM * Uniform
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformBlock
+**
+**  Get the gcsUNIFORM_BLOCK object pointer for an indexed uniform block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT Index
+**          Index of uniform to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcsUNIFORM_BLOCK * UniformBlock
+**          Pointer to a variable receiving the gcsUNIFORM_BLOCK object pointer.
+*/
+gceSTATUS
+gcSHADER_GetUniformBlock(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcsUNIFORM_BLOCK * UniformBlock
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetUniformBlockUniform
+**
+**  Get the gcUNIFORM object pointer for an indexed uniform of an indexed uniform
+**  block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcsUNIFORM_BLOCK UniformBlock
+**          Pointer to uniform block to retreive the uniform.
+**
+**      gctUINT Index
+**          Index of uniform to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcUNIFORM * Uniform
+**          Pointer to a variable receiving the gcUNIFORM object pointer.
+*/
+gceSTATUS
+gcSHADER_GetUniformBlockUniform(
+    IN gcSHADER Shader,
+    IN gcsUNIFORM_BLOCK UniformBlock,
+    IN gctUINT Index,
+    OUT gcUNIFORM * Uniform
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetStorageBlockVariable
+**
+**  Get the gcVARIABLE object pointer for an indexed variable of a storage
+**  block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcsSTORAGE_BLOCK StorageBlock
+**          Pointer to storage block to retreive the variable.
+**
+**      gctUINT Index
+**          Index of variable to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcVARIABLE * Variable
+**          Pointer to a variable receiving the gcVARIABLE object pointer.
+*/
+gceSTATUS
+gcSHADER_GetStorageBlockVariable(
+    IN gcSHADER Shader,
+    IN gcsSTORAGE_BLOCK StorageBlock,
+    IN gctUINT Index,
+    OUT gcVARIABLE * Variable
+    );
+
+/*******************************************************************************
+**                    gcSHADER_AddStorageBlock
+********************************************************************************
+**
+**    Add a uniform block to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the uniform block to add.
+**
+**        gcsSHADER_VAR_INFO *BlockInfo
+**            block info associated with uniform block to be added.
+**
+**        gceINTERFACE_BLOCK_LAYOUT_ID  MemoryLayout;
+**             Memory layout qualifier for members in block
+**
+**    OUTPUT:
+**
+**        gcsUNIFORM_BLOCK * StorageBlock
+**            Pointer to a variable receiving the gcsUNIFORM_BLOCK object pointer.
+**
+*/
+gceSTATUS
+gcSHADER_AddStorageBlock(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcsSHADER_VAR_INFO *BlockInfo,
+    IN gceINTERFACE_BLOCK_LAYOUT_ID MemoryLayout,
+    OUT gcsSTORAGE_BLOCK * StorageBlock
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetStorageBlockCount
+**
+**  Get the number of storage blocks for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of storage blocks.
+*/
+gceSTATUS
+gcSHADER_GetStorageBlockCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetStorageBlock
+**
+**  Get the gcsSTORAGE_BLOCK object pointer for an indexed storage block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT Index
+**          Index of storage block to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcsSTORAGE_BLOCK * StorageBlock
+**          Pointer to a variable receiving the gcsSTORAGE_BLOCK object pointer.
+*/
+gceSTATUS
+gcSHADER_GetStorageBlock(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcsSTORAGE_BLOCK * StorageBlock
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetIoBlockVariable
+**
+**  Get the gcVARIABLE object pointer for an indexed variable of a storage
+**  block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcsIO_BLOCK IoBlock
+**          Pointer to io block to retreive the variable.
+**
+**      gctUINT Index
+**          Index of variable to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcVARIABLE * Variable
+**          Pointer to a variable receiving the gcVARIABLE object pointer.
+*/
+gceSTATUS
+gcSHADER_GetIoBlockVariable(
+    IN gcSHADER Shader,
+    IN gcsIO_BLOCK IoBlock,
+    IN gctUINT Index,
+    OUT gcVARIABLE * Variable
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetIoBlockVariableCount
+**
+**  Get the number of variables in a io block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcsIO_BLOCK IoBlock
+**          Pointer to io block to retreive the variable count.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of variables in block.
+*/
+gceSTATUS
+gcSHADER_GetIoBlockVariableCount(
+    IN gcSHADER Shader,
+    gcsIO_BLOCK IoBlock,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**                    gcSHADER_AddIoBlock
+********************************************************************************
+**
+**    Add a IO block to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the IO block to add.
+**
+**        gctCONST_STRING InstanceName
+**            Instance name of the IO block to add.
+**
+**        gcsSHADER_VAR_INFO *BlockInfo
+**            block info associated with uniform block to be added.
+**
+**        gceINTERFACE_BLOCK_LAYOUT_ID  MemoryLayout;
+**             Memory layout qualifier for members in block
+**
+**    OUTPUT:
+**
+**        gcsUNIFORM_BLOCK * IoBlock
+**            Pointer to a variable receiving the gcsUNIFORM_BLOCK object pointer.
+**
+*/
+gceSTATUS
+gcSHADER_AddIoBlock(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gctCONST_STRING InstanceName,
+    IN gcsSHADER_VAR_INFO *BlockInfo,
+    IN gceINTERFACE_BLOCK_LAYOUT_ID MemoryLayout,
+    OUT gcsIO_BLOCK * IoBlock
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetIoBlockCount
+**
+**  Get the number of io blocks for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of io blocks.
+*/
+gceSTATUS
+gcSHADER_GetIoBlockCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetIoBlock
+**
+**  Get the gcsIO_BLOCK object pointer for an indexed io block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT Index
+**          Index of io block to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcsIO_BLOCK * IoBlock
+**          Pointer to a variable receiving the gcsIO_BLOCK object pointer.
+*/
+gceSTATUS
+gcSHADER_GetIoBlock(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcsIO_BLOCK * IoBlock
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetIoBlockByName
+**
+**  Get the gcsIO_BLOCK object pointer for an indexed io block for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctCONST_STRING BlockName
+**          Block name of io block to retreive the name for.
+**
+**      gctCONST_STRING InstanceName
+**          Instance name of io block to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcsIO_BLOCK * IoBlock
+**          Pointer to a variable receiving the gcsIO_BLOCK object pointer.
+*/
+gceSTATUS
+gcSHADER_GetIoBlockByName(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING BlockName,
+    IN gctCONST_STRING InstanceName,
+    OUT gcsIO_BLOCK * IoBlock
+    );
+
+/*******************************************************************************
+**                             gcSHADER_GetUniformIndexingRange
+********************************************************************************
+**
+**    Get the gcUNIFORM object pointer for an indexed uniform for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctINT uniformIndex
+**            Index of the start uniform.
+**
+**        gctINT offset
+**            Offset to indexing.
+**
+**    OUTPUT:
+**
+**        gctINT * LastUniformIndex
+**            Pointer to index of last uniform in indexing range.
+**
+**        gctINT * OffsetUniformIndex
+**            Pointer to index of uniform that indexing at offset.
+**
+**        gctINT * DeviationInOffsetUniform
+**            Pointer to offset in uniform picked up.
+*/
+gceSTATUS
+gcSHADER_GetUniformIndexingRange(
+    IN gcSHADER Shader,
+    IN gctINT uniformIndex,
+    IN gctINT offset,
+    OUT gctINT * LastUniformIndex,
+    OUT gctINT * OffsetUniformIndex,
+    OUT gctINT * DeviationInOffsetUniform
+    );
+
+/*******************************************************************************
+**                             gcSHADER_GetUniformByPhysicalAddress
+********************************************************************************
+**
+**    Get the gcUNIFORM object pointer by physical address for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctINT Index
+**            physical address of the uniform.
+**
+**    OUTPUT:
+**
+**        gcUNIFORM * Uniform
+**            Pointer to a variable receiving the gcUNIFORM object pointer.
+*/
+gceSTATUS
+gcSHADER_GetUniformByPhysicalAddress(
+    IN gcSHADER Shader,
+    IN gctINT PhysicalAddress,
+    OUT gcUNIFORM * Uniform
+    );
+
+/*******************************************************************************
+**                             gcSHADER_ComputeUniformPhysicalAddress
+********************************************************************************
+**
+**    Compuate the gcUNIFORM object pointer for this shader.
+**
+**    INPUT:
+**
+**        gctUINT32 HwConstRegBases
+**            Base physical addresses for the uniform.
+**
+**        gctUINT32 PsBaseAddress
+**            Fragment Base physical address for the uniform.
+**
+**        gcUNIFORM Uniform
+**            The uniform pointer.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * PhysicalAddress
+**            Pointer to a variable receiving the physical address.
+*/
+gceSTATUS
+gcSHADER_ComputeUniformPhysicalAddress(
+    IN gctUINT32 HwConstRegBases[],
+    IN gcUNIFORM Uniform,
+    OUT gctUINT32 * PhysicalAddress
+    );
+
+/*******************************************************************************
+**  gcSHADER_ReallocateUniformBlocks
+**
+**  Reallocate an array of pointers to gcUNIFORM_BLOCK objects.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcSHADER_ReallocateUniformBlocks(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count
+    );
+
+/*******************************************************************************
+**                    gcSHADER_AddUniformBlock
+********************************************************************************
+**
+**    Add a uniform block to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the uniform block to add.
+**
+**        gcsSHADER_VAR_INFO *BlockInfo
+**            block info associated with uniform block to be added.
+**
+**        gceINTERFACE_BLOCK_LAYOUT_ID  MemoryLayout;
+**             Memory layout qualifier for members in block
+**
+**    OUTPUT:
+**
+**        gcsUNIFORM_BLOCK * Uniform
+**            Pointer to a variable receiving the gcsUNIFORM_BLOCK object pointer.
+**
+*/
+gceSTATUS
+gcSHADER_AddUniformBlock(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcsSHADER_VAR_INFO *BlockInfo,
+    IN gceINTERFACE_BLOCK_LAYOUT_ID  MemoryLayout,
+    IN gctINT16 ArrayIndex,
+    IN gctUINT16 ArrayLength,
+    OUT gcsUNIFORM_BLOCK * UniformBlock
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetFunctionByName
+**
+**  Get the gcFUNCTION object pointer for an named kernel function for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT FunctionName
+**          Name of kernel function to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcFUNCTION * Function
+**          Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
+*/
+gceSTATUS
+gcSHADER_GetFunctionByName(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING FunctionName,
+    OUT gcFUNCTION * Function
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetFunctionByHeadIndex
+**
+**  Get the gcFUNCTION object pointer for an named kernel function for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT FunctionHeadIndex
+**          Head index of kernel function to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcFUNCTION * Function
+**          Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
+*/
+gceSTATUS
+gcSHADER_GetFunctionByHeadIndex(
+    IN     gcSHADER         Shader,
+    IN     gctUINT HeadIndex,
+    OUT    gcFUNCTION * Function
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetKernelFunctionByHeadIndex
+**
+**  Get the gcKERNEL_FUNCTION object pointer for an named kernel function for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT FunctionHeadIndex
+**          Head index of kernel function to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcKERNEL_FUNCTION * Function
+**          Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
+*/
+gceSTATUS
+gcSHADER_GetKernelFunctionByHeadIndex(
+    IN  gcSHADER            Shader,
+    IN  gctUINT             HeadIndex,
+    OUT gcKERNEL_FUNCTION * Function
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetKernelFucntion
+**
+**  Get the gcKERNEL_FUNCTION object pointer for an indexed kernel function for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT Index
+**          Index of kernel function to retreive the name for.
+**
+**  OUTPUT:
+**
+**      gcKERNEL_FUNCTION * KernelFunction
+**          Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
+*/
+gceSTATUS
+gcSHADER_GetKernelFunction(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcKERNEL_FUNCTION * KernelFunction
+    );
+
+gceSTATUS
+gcSHADER_GetKernelFunctionByName(
+    IN gcSHADER Shader,
+    IN gctSTRING KernelName,
+    OUT gcKERNEL_FUNCTION * KernelFunction
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetKernelFunctionCount
+**
+**  Get the number of kernel functions for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Count
+**          Pointer to a variable receiving the number of kernel functions.
+*/
+gceSTATUS
+gcSHADER_GetKernelFunctionCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_ReallocateOutputs
+**
+**  Reallocate an array of pointers to gcOUTPUT objects.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcSHADER_ReallocateOutputs(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count
+    );
+
+/*******************************************************************************
+**                               gcSHADER_AddOutput
+********************************************************************************
+**
+**    Add an output to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the output to add.
+**
+**        gcSHADER_TYPE Type
+**            Type of the output to add.
+**
+**        gctUINT32 Length
+**            Array length of the output to add.  'Length' must be at least 1.
+**
+**        gctUINT32 TempRegister
+**            Temporary register index that holds the output value.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOutput(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gctUINT32 Length,
+    IN gctUINT32 TempRegister,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddOutputWithLocation
+**
+**  Add an output with an associated location to a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctCONST_STRING Name
+**          Name of the output to add.
+**
+**      gcSHADER_TYPE Type
+**          Type of the output to add.
+**
+**    gcSHADER_PRECISION Precision
+**          Precision of the output.
+**
+**      gctUINT32 Length
+**          Array length of the output to add.  'Length' must be at least 1.
+**
+**      gctUINT32 TempRegister
+**          Temporary register index that holds the output value.
+**
+**      gctINT Location
+**          Location associated with the output.
+**
+**  OUTPUT:
+**
+**      gcOUTPUT * Output
+**          Pointer to an output receiving the gcOUTPUT object pointer.
+*/
+gceSTATUS
+gcSHADER_AddOutputWithLocation(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gcSHADER_PRECISION Precision,
+    IN gctBOOL IsArray,
+    IN gctUINT32 Length,
+    IN gctUINT32 TempRegister,
+    IN gcSHADER_SHADERMODE shaderMode,
+    IN gctINT Location,
+    IN gctINT FieldIndex,
+    IN gctBOOL IsInvariant,
+    IN gctBOOL IsPrecise,
+    OUT gcOUTPUT * Output
+    );
+
+gctINT
+gcSHADER_GetOutputDefaultLocation(
+    IN gcSHADER Shader
+    );
+
+gceSTATUS
+gcSHADER_AddOutputIndexed(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gctUINT32 Index,
+    IN gctUINT32 TempIndex
+    );
+
+/*******************************************************************************
+**  gcOUTPUT_SetType
+**
+**  Set the type of an output.
+**
+**  INPUT:
+**
+**      gcOUTPUT Output
+**          Pointer to a gcOUTPUT object.
+**
+**      gcSHADER_TYPE Type
+**          Type of the output.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcOUTPUT_SetType(
+    IN gcOUTPUT Output,
+    IN gcSHADER_TYPE Type
+    );
+
+/*******************************************************************************
+**                             gcSHADER_GetOutputCount
+********************************************************************************
+**
+**    Get the number of outputs for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Count
+**            Pointer to a variable receiving the number of outputs.
+*/
+gceSTATUS
+gcSHADER_GetOutputCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**                               gcSHADER_GetOutput
+********************************************************************************
+**
+**    Get the gcOUTPUT object pointer for an indexed output for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT Index
+**            Index of output to retrieve.
+**
+**    OUTPUT:
+**
+**        gcOUTPUT * Output
+**            Pointer to a variable receiving the gcOUTPUT object pointer.
+*/
+gceSTATUS
+gcSHADER_GetOutput(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcOUTPUT * Output
+    );
+
+
+/*******************************************************************************
+**                               gcSHADER_GetOutputByName
+********************************************************************************
+**
+**    Get the gcOUTPUT object pointer for this shader by output name.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctSTRING name
+**            Name of output to retrieve.
+**
+**      gctUINT32 nameLength
+**          Length of name to retrieve
+**
+**    OUTPUT:
+**
+**        gcOUTPUT * Output
+**            Pointer to a variable receiving the gcOUTPUT object pointer.
+*/
+gceSTATUS
+gcSHADER_GetOutputByName(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING name,
+    IN gctUINT32 nameLength,
+    OUT gcOUTPUT * Output
+    );
+
+/*******************************************************************************
+**                               gcSHADER_GetOutputByTempIndex
+********************************************************************************
+**
+**    Get the gcOUTPUT object pointer for this shader by output temp index.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT32 TempIndex
+**            Temp index of output to retrieve.
+**
+**
+**    OUTPUT:
+**
+**        gcOUTPUT * Output
+**            Pointer to a variable receiving the gcOUTPUT object pointer.
+*/
+gceSTATUS
+gcSHADER_GetOutputByTempIndex(
+    IN gcSHADER Shader,
+    IN gctUINT32 TempIndex,
+    OUT gcOUTPUT * Output
+    );
+
+gceSTATUS
+gcSHADER_GetOutputIndexByOutput(
+    IN gcSHADER Shader,
+    IN gcOUTPUT Output,
+    IN OUT gctINT16 * Index
+    );
+
+/*******************************************************************************
+**  gcSHADER_ReallocateVariables
+**
+**  Reallocate an array of pointers to gcVARIABLE objects.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcSHADER_ReallocateVariables(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count
+    );
+
+/*******************************************************************************
+**                               gcSHADER_AddVariable
+********************************************************************************
+**
+**    Add a variable to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctCONST_STRING Name
+**            Name of the variable to add.
+**
+**        gcSHADER_TYPE Type
+**            Type of the variable to add.
+**
+**        gctUINT32 Length
+**            Array length of the variable to add.  'Length' must be at least 1.
+**
+**        gctUINT32 TempRegister
+**            Temporary register index that holds the variable value.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddVariable(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gctUINT32 Length,
+    IN gctUINT32 TempRegister
+    );
+
+
+/*******************************************************************************
+**  gcSHADER_AddVariableEx
+********************************************************************************
+**
+**  Add a variable to a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctCONST_STRING Name
+**          Name of the variable to add.
+**
+**      gcSHADER_TYPE Type
+**          Type of the variable to add.
+**
+**      gctUINT32 Length
+**          Array length of the variable to add.  'Length' must be at least 1.
+**
+**      gctUINT32 TempRegister
+**          Temporary register index that holds the variable value.
+**
+**      gcSHADER_VAR_CATEGORY varCategory
+**          Variable category, normal or struct.
+**
+**      gctUINT16 numStructureElement
+**          If struct, its element number.
+**
+**      gctINT16 parent
+**          If struct, parent index in gcSHADER.variables.
+**
+**      gctINT16 prevSibling
+**          If struct, previous sibling index in gcSHADER.variables.
+**
+**  OUTPUT:
+**
+**      gctINT16* ThisVarIndex
+**          Returned value about variable index in gcSHADER.
+*/
+gceSTATUS
+gcSHADER_AddVariableEx(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gctINT ArrayLengthCount,
+    IN gctINT * ArrayLengthList,
+    IN gctUINT32 TempRegister,
+    IN gcSHADER_VAR_CATEGORY varCategory,
+    IN gctUINT8 Precision,
+    IN gctUINT16 numStructureElement,
+    IN gctINT16 parent,
+    IN gctINT16 prevSibling,
+    OUT gctINT16* ThisVarIndex
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddVariableEx1
+**
+**  Add a variable to a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctCONST_STRING Name
+**          Name of the variable to add.
+**
+**      gctUINT32 TempRegister
+**          Temporary register index that holds the variable value.
+**
+**      gcsSHADER_VAR_INFO *VarInfo
+**          Variable information struct pointer.
+**
+**  OUTPUT:
+**
+**      gctINT16* ThisVarIndex
+**          Returned value about variable index in gcSHADER.
+*/
+gceSTATUS
+gcSHADER_AddVariableEx1(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    IN gctUINT32 TempRegister,
+    IN gcsSHADER_VAR_INFO *VarInfo,
+    OUT gctINT16* ThisVarIndex
+    );
+
+/*******************************************************************************
+**  gcSHADER_UpdateVariable
+********************************************************************************
+**
+**  Update a variable to a gcSHADER object.
+**
+**  INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT Index
+**            Index of variable to retrieve.
+**
+**        gceVARIABLE_UPDATE_FLAGS flag
+**            Flag which property of variable will be updated.
+**
+**      gctUINT newValue
+**          New value to update.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_UpdateVariable(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    IN gceVARIABLE_UPDATE_FLAGS flag,
+    IN gctUINT newValue
+    );
+
+gceSTATUS
+gcSHADER_CopyVariable(
+    IN gcSHADER Shader,
+    IN gcVARIABLE Variable,
+    IN gctUINT16 * Index
+    );
+
+/*******************************************************************************
+**                             gcSHADER_GetVariableCount
+********************************************************************************
+**
+**    Get the number of variables for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Count
+**            Pointer to a variable receiving the number of variables.
+*/
+gceSTATUS
+gcSHADER_GetVariableCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetTempCount
+**
+**  Get the number of temp register used for this shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      return the Shader's temp register count, included in
+**      variable, output, arguments, temporay in instruciton
+ */
+gctUINT
+gcSHADER_GetTempCount(
+    IN gcSHADER        Shader
+    );
+
+/*******************************************************************************
+**                               gcSHADER_GetVariable
+********************************************************************************
+**
+**    Get the gcVARIABLE object pointer for an indexed variable for this shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT Index
+**            Index of variable to retrieve.
+**
+**    OUTPUT:
+**
+**        gcVARIABLE * Variable
+**            Pointer to a variable receiving the gcVARIABLE object pointer.
+*/
+gceSTATUS
+gcSHADER_GetVariable(
+    IN gcSHADER Shader,
+    IN gctUINT Index,
+    OUT gcVARIABLE * Variable
+    );
+
+gceSTATUS
+gcSHADER_GetVariableByName(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING VariableName,
+    IN gctUINT16 NameLength,
+    OUT gcVARIABLE * Variable
+    );
+
+/*******************************************************************************
+**                               gcSHADER_GetVariableIndexingRange
+********************************************************************************
+**
+**    Get the gcVARIABLE indexing range.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcVARIABLE variable
+**            Start variable.
+**
+**        gctBOOL whole
+**            Indicate whether maximum indexing range is queried
+**
+**    OUTPUT:
+**
+**        gctUINT *Start
+**            Pointer to range start (temp register index).
+**
+**        gctUINT *End
+**            Pointer to range end (temp register index).
+*/
+gceSTATUS
+gcSHADER_GetVariableIndexingRange(
+    IN gcSHADER Shader,
+    IN gcVARIABLE variable,
+    IN gctBOOL whole,
+    OUT gctUINT *Start,
+    OUT gctUINT *End
+    );
+
+/*******************************************************************************
+**                               gcSHADER_AddOpcode
+********************************************************************************
+**
+**    Add an opcode to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcSL_OPCODE Opcode
+**            Opcode to add.
+**
+**        gctUINT32 TempRegister
+**            Temporary register index that acts as the target of the opcode.
+**
+**        gctUINT8 Enable
+**            Write enable bits for the temporary register that acts as the target
+**            of the opcode.
+**
+**        gcSL_FORMAT Format
+**            Format of the temporary register.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcode(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gctUINT32 TempRegister,
+    IN gctUINT8 Enable,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision,
+    IN gctUINT32 srcLoc
+    );
+
+gceSTATUS
+gcSHADER_AddOpcode2(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gcSL_CONDITION Condition,
+    IN gctUINT32 TempRegister,
+    IN gctUINT8 Enable,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**                            gcSHADER_AddOpcodeIndexed
+********************************************************************************
+**
+**    Add an opcode to a gcSHADER object that writes to an dynamically indexed
+**    target.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcSL_OPCODE Opcode
+**            Opcode to add.
+**
+**        gctUINT32 TempRegister
+**            Temporary register index that acts as the target of the opcode.
+**
+**        gctUINT8 Enable
+**            Write enable bits  for the temporary register that acts as the
+**            target of the opcode.
+**
+**        gcSL_INDEXED Mode
+**            Location of the dynamic index inside the temporary register.  Valid
+**            values can be:
+**
+**                gcSL_INDEXED_X - Use x component of the temporary register.
+**                gcSL_INDEXED_Y - Use y component of the temporary register.
+**                gcSL_INDEXED_Z - Use z component of the temporary register.
+**                gcSL_INDEXED_W - Use w component of the temporary register.
+**
+**        gctUINT16 IndexRegister
+**            Temporary register index that holds the dynamic index.
+**
+**        gcSL_FORMAT Format
+**            Format of the temporary register.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcodeIndexed(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gctUINT32 TempRegister,
+    IN gctUINT8 Enable,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddOpcodeIndexedWithPrecision
+**
+**  Add an opcode to a gcSHADER object that writes to an dynamically indexed
+**  target with precision setting.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_OPCODE Opcode
+**          Opcode to add.
+**
+**      gctUINT32 TempRegister
+**          Temporary register index that acts as the target of the opcode.
+**
+**      gctUINT8 Enable
+**          Write enable bits  for the temporary register that acts as the
+**          target of the opcode.
+**
+**      gcSL_INDEXED Mode
+**          Location of the dynamic index inside the temporary register.  Valid
+**          values can be:
+**
+**              gcSL_INDEXED_X - Use x component of the temporary register.
+**              gcSL_INDEXED_Y - Use y component of the temporary register.
+**              gcSL_INDEXED_Z - Use z component of the temporary register.
+**              gcSL_INDEXED_W - Use w component of the temporary register.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**      gcSHADER_PRECISION Precision
+**          Precision of register.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcodeIndexedWithPrecision(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gctUINT32 TempRegister,
+    IN gctUINT8 Enable,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddOpcodeConditionIndexed
+**
+**  Add an opcode to a gcSHADER object that writes to an dynamically indexed
+**  target.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_OPCODE Opcode
+**          Opcode to add.
+**
+**      gcSL_CONDITION Condition
+**          Condition to check.
+**
+**      gctUINT32 TempRegister
+**          Temporary register index that acts as the target of the opcode.
+**
+**      gctUINT8 Enable
+**          Write enable bits  for the temporary register that acts as the
+**          target of the opcode.
+**
+**      gcSL_INDEXED Indexed
+**          Location of the dynamic index inside the temporary register.  Valid
+**          values can be:
+**
+**              gcSL_INDEXED_X - Use x component of the temporary register.
+**              gcSL_INDEXED_Y - Use y component of the temporary register.
+**              gcSL_INDEXED_Z - Use z component of the temporary register.
+**              gcSL_INDEXED_W - Use w component of the temporary register.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcodeConditionIndexed(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gcSL_CONDITION Condition,
+    IN gctUINT32 TempRegister,
+    IN gctUINT8 Enable,
+    IN gcSL_INDEXED Indexed,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddOpcodeConditionIndexedWithPrecision
+**
+**  Add an opcode to a gcSHADER object that writes to an dynamically indexed
+**  target with precision.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_OPCODE Opcode
+**          Opcode to add.
+**
+**      gcSL_CONDITION Condition
+**          Condition to check.
+**
+**      gctUINT32 TempRegister
+**          Temporary register index that acts as the target of the opcode.
+**
+**      gctUINT8 Enable
+**          Write enable bits  for the temporary register that acts as the
+**          target of the opcode.
+**
+**      gcSL_INDEXED Indexed
+**          Location of the dynamic index inside the temporary register.  Valid
+**          values can be:
+**
+**              gcSL_INDEXED_X - Use x component of the temporary register.
+**              gcSL_INDEXED_Y - Use y component of the temporary register.
+**              gcSL_INDEXED_Z - Use z component of the temporary register.
+**              gcSL_INDEXED_W - Use w component of the temporary register.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**      gcSHADER_PRECISION Precision
+**          Precision of register.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcodeConditionIndexedWithPrecision(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gcSL_CONDITION Condition,
+    IN gctUINT32 TempRegister,
+    IN gctUINT8 Enable,
+    IN gcSL_INDEXED Indexed,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**                          gcSHADER_AddOpcodeConditional
+********************************************************************************
+**
+**    Add an conditional opcode to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcSL_OPCODE Opcode
+**            Opcode to add.
+**
+**        gcSL_CONDITION Condition
+**            Condition that needs to evaluate to gcvTRUE in order for the opcode to
+**            execute.
+**
+**        gctUINT Label
+**            Target label if 'Condition' evaluates to gcvTRUE.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcodeConditional(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gcSL_CONDITION Condition,
+    IN gctUINT Label,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddOpcodeConditionalFormatted
+**
+**  Add an conditional jump or call opcode to a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_OPCODE Opcode
+**          Opcode to add.
+**
+**      gcSL_CONDITION Condition
+**          Condition that needs to evaluate to gcvTRUE in order for the opcode to
+**          execute.
+**
+**      gcSL_FORMAT Format
+**          Format of conditional operands
+**
+**      gctUINT Label
+**          Target label if 'Condition' evaluates to gcvTRUE.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcodeConditionalFormatted(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gcSL_CONDITION Condition,
+    IN gcSL_FORMAT Format,
+    IN gctUINT Label,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddOpcodeConditionalFormattedEnable
+**
+**  Add an conditional jump or call opcode to a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_OPCODE Opcode
+**          Opcode to add.
+**
+**      gcSL_CONDITION Condition
+**          Condition that needs to evaluate to gcvTRUE in order for the opcode to
+**          execute.
+**
+**      gcSL_FORMAT Format
+**          Format of conditional operands
+**
+**      gctUINT8 Enable
+**          Write enable value for the target of the opcode.
+**
+**      gctUINT Label
+**          Target label if 'Condition' evaluates to gcvTRUE.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddOpcodeConditionalFormattedEnable(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE Opcode,
+    IN gcSL_CONDITION Condition,
+    IN gcSL_FORMAT Format,
+    IN gctUINT8 Enable,
+    IN gctUINT Label,
+    IN gctUINT32 srcLoc
+    );
+
+/*******************************************************************************
+**  gcSHADER_FindNextUsedLabelId
+**
+**  Find a label id which is not used inside the gcSHADER object
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  RETURN:
+**
+**      the next unused label id
+*/
+gctUINT
+gcSHADER_FindNextUsedLabelId(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**  gcSHADER_FindLabel
+**
+**  Find a label inside the gcSHADER object
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a  gcSHADER object.
+**
+**      gctUINT Label
+**          Label identifier.
+**
+**  OUTPUT:
+**
+**      gcSHADER_LABEL * ShaderLabel
+**          Pointer to a variable receiving the pointer to the gcSHADER_LABEL
+**          structure representing the requested label.
+*/
+gctBOOL
+gcSHADER_FindLabel(
+    IN gcSHADER Shader,
+    IN gctUINT Label,
+    OUT gcSHADER_LABEL * ShaderLabel
+    );
+
+/*******************************************************************************
+**                                gcSHADER_AddLabel
+********************************************************************************
+**
+**    Define a label at the current instruction of a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT Label
+**            Label to define.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddLabel(
+    IN gcSHADER Shader,
+    IN gctUINT Label
+    );
+
+/*******************************************************************************
+**  gcSHADER_FindFunctionByLabel
+**
+**  Find a function inside the gcSHADER object by call target (label)
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a  gcSHADER object.
+**
+**      gctUINT Label
+**          Label identifier.
+**
+**  OUTPUT:
+**
+**      gcFUNCTION * Function
+**          Pointer to a variable receiving the pointer to the gcFUNCTION
+*/
+gctBOOL
+gcSHADER_FindFunctionByLabel(
+    IN gcSHADER Shader,
+    IN gctUINT Label,
+    OUT gcFUNCTION * Function
+    );
+
+/*****************************************************************************************************
+**  gcSHADER_UpdateTargetPacked
+**
+**  Update instruction target's PackedComponents field to indicate the number of packed components
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctINT Components
+**          Number of packed components.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_UpdateTargetPacked(
+    IN gcSHADER Shader,
+    IN gctINT Components
+    );
+
+/*******************************************************************************
+**  gcSHADER_UpdateSourcePacked
+**
+**  Update source's PackedComponents field to indicate the number of packed components
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSHADER_INSTRUCTION_INDEX InstIndex
+**          Instruction argument index: gcSHADER_SOURCE0/gcSHADER_SOURCE1.
+**
+**      gctINT Components
+**          Number of packed components.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_UpdateSourcePacked(
+    IN gcSHADER Shader,
+    IN gcSHADER_INSTRUCTION_INDEX InstrIndex,
+    IN gctINT Components
+    );
+
+/*******************************************************************************
+**  gcSHADER_UpdateResOpType
+**
+**  Update the resOpType
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_OPCODE_RES_TYPE ResOpType
+**
+**      gctINT Components
+**          Number of packed components.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_UpdateResOpType(
+    IN gcSHADER Shader,
+    IN gcSL_OPCODE_RES_TYPE OpCodeResType
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddRoundingMode
+**
+**  Add rounding mode to a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_ROUND Round
+**          Type of the source operand.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddRoundingMode(
+    IN gcSHADER Shader,
+    IN gcSL_ROUND Round
+    );
+
+
+/*******************************************************************************
+**  gcSHADER_AddSaturation
+**
+**  Add saturation modifier to a gcSHADER instruction.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_MODIFIER_SAT Sat
+**          Saturation modifier.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSaturation(
+    IN gcSHADER Shader,
+    IN gcSL_MODIFIER_SAT  Sat
+    );
+
+/*******************************************************************************
+**  gcSHADER_NewTempRegs
+**
+**  Allocate RegCount of temp registers from the shader.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT RegCount
+**          Count of temp register be allocated.
+**
+**      gcSHADER_TYPE  Type
+**          Type of the temp register.
+**
+**
+**  Return:
+**
+**      The start temp register index, the next available temp register
+**      index is the return value plus RegCount.
+*/
+gctUINT32
+gcSHADER_NewTempRegs(
+    IN gcSHADER       Shader,
+    IN gctUINT        RegCount,
+    IN gcSHADER_TYPE  Type
+    );
+
+gctUINT32
+gcSHADER_UpdateTempRegCount(
+    IN gcSHADER       Shader,
+    IN gctUINT        RegCount
+    );
+
+gctUINT32
+gcSHADER_EndInst(
+    IN gcSHADER Shader
+    );
+/*******************************************************************************
+**                               gcSHADER_AddSource
+********************************************************************************
+**
+**    Add a source operand to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcSL_TYPE Type
+**            Type of the source operand.
+**
+**        gctUINT32 SourceIndex
+**            Index of the source operand.
+**
+**        gctUINT8 Swizzle
+**            x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**        gcSL_FORMAT Format
+**            Format of the source operand.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSource(
+    IN gcSHADER Shader,
+    IN gcSL_TYPE Type,
+    IN gctUINT32 SourceIndex,
+    IN gctUINT8 Swizzle,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/*******************************************************************************
+**                            gcSHADER_AddSourceIndexed
+********************************************************************************
+**
+**    Add a dynamically indexed source operand to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcSL_TYPE Type
+**            Type of the source operand.
+**
+**        gctUINT32 SourceIndex
+**            Index of the source operand.
+**
+**        gctUINT8 Swizzle
+**            x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**        gcSL_INDEXED Mode
+**            Addressing mode for the index.
+**
+**        gctUINT16 IndexRegister
+**            Temporary register index that holds the dynamic index.
+**
+**        gcSL_FORMAT Format
+**            Format of the source operand.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceIndexed(
+    IN gcSHADER Shader,
+    IN gcSL_TYPE Type,
+    IN gctUINT32 SourceIndex,
+    IN gctUINT8 Swizzle,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddSourceIndexedWithPrecision
+**
+**  Add a dynamically indexed source operand to a gcSHADER object with precision.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcSL_TYPE Type
+**          Type of the source operand.
+**
+**      gctUINT32 SourceIndex
+**          Index of the source operand.
+**
+**      gctUINT8 Swizzle
+**          x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**      gcSL_INDEXED Mode
+**          Addressing mode for the index.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**    gcSHADER_PRECISION Precision
+**        Precision of source value
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceIndexedWithPrecision(
+    IN gcSHADER Shader,
+    IN gcSL_TYPE Type,
+    IN gctUINT32 SourceIndex,
+    IN gctUINT8 Swizzle,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/*******************************************************************************
+**                           gcSHADER_AddSourceAttribute
+********************************************************************************
+**
+**    Add an attribute as a source operand to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcATTRIBUTE Attribute
+**            Pointer to a gcATTRIBUTE object.
+**
+**        gctUINT8 Swizzle
+**            x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**        gctINT Index
+**            Static index into the attribute in case the attribute is a matrix
+**            or array.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceAttribute(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index
+    );
+
+/*******************************************************************************
+**                           gcSHADER_AddSourceAttributeIndexed
+********************************************************************************
+**
+**    Add an indexed attribute as a source operand to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcATTRIBUTE Attribute
+**            Pointer to a gcATTRIBUTE object.
+**
+**        gctUINT8 Swizzle
+**            x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**        gctINT Index
+**            Static index into the attribute in case the attribute is a matrix
+**            or array.
+**
+**        gcSL_INDEXED Mode
+**            Addressing mode of the dynamic index.
+**
+**        gctUINT16 IndexRegister
+**            Temporary register index that holds the dynamic index.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceAttributeIndexed(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister
+    );
+
+/*******************************************************************************
+**                            gcSHADER_AddSourceUniform
+********************************************************************************
+**
+**    Add a uniform as a source operand to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**        gctUINT8 Swizzle
+**            x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**        gctINT Index
+**            Static index into the uniform in case the uniform is a matrix or
+**            array.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceUniform(
+    IN gcSHADER Shader,
+    IN gcUNIFORM Uniform,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index
+    );
+
+/*******************************************************************************
+**                        gcSHADER_AddSourceUniformIndexed
+********************************************************************************
+**
+**    Add an indexed uniform as a source operand to a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**        gctUINT8 Swizzle
+**            x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**        gctINT Index
+**            Static index into the uniform in case the uniform is a matrix or
+**            array.
+**
+**        gcSL_INDEXED Mode
+**            Addressing mode of the dynamic index.
+**
+**        gctUINT16 IndexRegister
+**            Temporary register index that holds the dynamic index.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceUniformIndexed(
+    IN gcSHADER Shader,
+    IN gcUNIFORM Uniform,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister
+    );
+
+gceSTATUS
+gcSHADER_AddSourceSamplerIndexed(
+    IN gcSHADER Shader,
+    IN gctUINT8 Swizzle,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister
+    );
+
+gceSTATUS
+gcSHADER_AddSourceAttributeFormatted(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_FORMAT Format
+    );
+
+gceSTATUS
+gcSHADER_AddSourceAttributeIndexedFormatted(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddSourceSamplerIndexedFormattedWithPrecision
+**
+**  Add a "0-based" formatted indexed sampler as a source operand to a gcSHADER
+**  object with precision.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT8 Swizzle
+**          x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**      gcSL_INDEXED Mode
+**          Addressing mode of the dynamic index.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**    gcSL_FORMAT Format
+**        Format of sampler value
+**
+**    gcSHADER_PRECISION Precision
+**        Precision of attribute value
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceSamplerIndexedFormattedWithPrecision(
+    IN gcSHADER Shader,
+    IN gctUINT8 Swizzle,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/********************************************************************************************
+**  gcSHADER_AddSourceAttributeIndexedFormattedWithPrecision
+**
+**  Add a formatted indexed attribute as a source operand to a gcSHADER object with precision.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcATTRIBUTE Attribute
+**          Pointer to a gcATTRIBUTE object.
+**
+**      gctUINT8 Swizzle
+**          x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**      gctINT Index
+**          Static index into the attribute in case the attribute is a matrix
+**          or array.
+**
+**      gcSL_INDEXED Mode
+**          Addressing mode of the dynamic index.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**    gcSL_FORMAT Format
+**        Format of indexed attribute value
+**
+**    gcSHADER_PRECISION Precision
+**        Precision of attribute value
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceAttributeIndexedFormattedWithPrecision(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/********************************************************************************************
+**  gcSHADER_AddSourceOutputIndexedFormattedWithPrecision
+**
+**  Add a formatted indexed output as a source operand to a gcSHADER object with precision.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcOUTPUT Output
+**          Pointer to a gcOUTPUT object.
+**
+**      gctUINT8 Swizzle
+**          x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**      gctINT Index
+**          Static index into the attribute in case the attribute is a matrix
+**          or array.
+**
+**      gcSL_INDEXED Mode
+**          Addressing mode of the dynamic index.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**    gcSL_FORMAT Format
+**        Format of indexed attribute value
+**
+**    gcSHADER_PRECISION Precision
+**        Precision of attribute value
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceOutputIndexedFormattedWithPrecision(
+    IN gcSHADER Shader,
+    IN gcOUTPUT Output,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+gceSTATUS
+gcSHADER_AddSourceUniformFormatted(
+    IN gcSHADER Shader,
+    IN gcUNIFORM Uniform,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_FORMAT Format
+    );
+
+gceSTATUS
+gcSHADER_AddSourceUniformIndexedFormatted(
+    IN gcSHADER Shader,
+    IN gcUNIFORM Uniform,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format
+    );
+
+/******************************************************************************************
+**  gcSHADER_AddSourceUniformIndexedFormattedWithPrecision
+**
+**  Add a formatted indexed uniform as a source operand to a gcSHADER object with Precision
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gcUNIFORM Uniform
+**          Pointer to a gcUNIFORM object.
+**
+**      gctUINT8 Swizzle
+**          x, y, z, and w swizzle values packed into one 8-bit value.
+**
+**      gctINT Index
+**          Static index into the uniform in case the uniform is a matrix or
+**          array.
+**
+**      gcSL_INDEXED Mode
+**          Addressing mode of the dynamic index.
+**
+**      gcSL_INDEXED_LEVEL IndexedLevel
+**          Indexed level of dynamic index.
+**
+**      gctUINT16 IndexRegister
+**          Temporary register index that holds the dynamic index.
+**
+**    gcSL_FORMAT Format
+**        Format of uniform value
+**
+**    gcSHADER_PRECISION Precision
+**        Precision of uniform value
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceUniformIndexedFormattedWithPrecision(
+    IN gcSHADER Shader,
+    IN gcUNIFORM Uniform,
+    IN gctUINT8 Swizzle,
+    IN gctINT Index,
+    IN gcSL_INDEXED Mode,
+    IN gcSL_INDEXED_LEVEL IndexedLevel,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+gceSTATUS
+gcSHADER_AddSourceSamplerIndexedFormatted(
+    IN gcSHADER Shader,
+    IN gctUINT8 Swizzle,
+    IN gcSL_INDEXED Mode,
+    IN gctUINT16 IndexRegister,
+    IN gcSL_FORMAT Format
+    );
+
+/*******************************************************************************
+**                           gcSHADER_AddSourceConstant
+********************************************************************************
+**
+**    Add a constant floating point value as a source operand to a gcSHADER
+**    object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctFLOAT Constant
+**            Floating point constant.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceConstant(
+    IN gcSHADER Shader,
+    IN gctFLOAT Constant
+    );
+
+/*******************************************************************************
+**                               gcSHADER_AddSourceConstantFormatted
+********************************************************************************
+**
+**    Add a constant value as a source operand to a gcSHADER
+**    object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        void * Constant
+**            Pointer to constant.
+**
+**        gcSL_FORMAT Format
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceConstantFormatted(
+    IN gcSHADER Shader,
+    IN void *Constant,
+    IN gcSL_FORMAT Format
+    );
+
+/*******************************************************************************
+**    gcSHADER_AddSourceConstantFormattedWithPrecision
+**
+**    Add a formatted constant value as a source operand to a gcSHADER object
+**    with precision.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        void *Constant
+**            Pointer to constant value (32 bits).
+**
+**        gcSL_FORMAT Format
+**            Format of constant value
+**
+**    gcSHADER_PRECISION Precision
+**        Precision of constant value
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AddSourceConstantFormattedWithPrecision(
+    IN gcSHADER Shader,
+    IN void *Constant,
+    IN gcSL_FORMAT Format,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/*******************************************************************************
+**                                  gcSHADER_Pack
+********************************************************************************
+**
+**    Pack a dynamically created gcSHADER object by trimming the allocated arrays
+**    and resolving all the labeling.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_Pack(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**                                  gcSHADER_ExpandArraysOfArrays
+********************************************************************************
+**
+**    Expand array size for a object if this object is an arrays of arrays.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_ExpandArraysOfArrays(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**                                  gcSHADER_AnalyzeFunctions
+********************************************************************************
+**
+** 1) Check function has sampler indexing
+** 2) Detect if there is a recursive function in the shader code
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_AnalyzeFunctions(
+    IN gcSHADER Shader,
+    IN gctBOOL NeedToCheckRecursive
+    );
+
+/*******************************************************************************
+**                                gcSHADER_SetOptimizationOption
+********************************************************************************
+**
+**    Set optimization option of a gcSHADER object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gctUINT OptimizationOption
+**            Optimization option.  Can be one of the following:
+**
+**                0                        - No optimization.
+**                1                        - Full optimization.
+**                Other value                - For optimizer testing.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcSHADER_SetOptimizationOption(
+    IN gcSHADER Shader,
+    IN gctUINT OptimizationOption
+    );
+
+/*******************************************************************************
+**  gcSHADER_ReallocateFunctions
+**
+**  Reallocate an array of pointers to gcFUNCTION objects.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcSHADER_ReallocateFunctions(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count
+    );
+
+gceSTATUS
+gcSHADER_AddFunction(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    OUT gcFUNCTION * Function
+    );
+
+gceSTATUS
+gcSHADER_DeleteFunction(
+    IN gcSHADER Shader,
+    IN gcFUNCTION  Function
+    );
+
+gceSTATUS
+gcSHADER_ReallocateKernelFunctions(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count
+    );
+
+gceSTATUS
+gcSHADER_AddKernelFunction(
+    IN gcSHADER Shader,
+    IN gctCONST_STRING Name,
+    OUT gcKERNEL_FUNCTION * KernelFunction
+    );
+
+gceSTATUS
+gcSHADER_BeginFunction(
+    IN gcSHADER Shader,
+    IN gcFUNCTION Function
+    );
+
+gceSTATUS
+gcSHADER_EndFunction(
+    IN gcSHADER Shader,
+    IN gcFUNCTION Function
+    );
+
+gceSTATUS
+gcSHADER_BeginKernelFunction(
+    IN gcSHADER Shader,
+    IN gcKERNEL_FUNCTION KernelFunction
+    );
+
+gceSTATUS
+gcSHADER_EndKernelFunction(
+    IN gcSHADER Shader,
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctUINT32 LocalMemorySize
+    );
+
+gceSTATUS
+gcSHADER_SetMaxKernelFunctionArgs(
+    IN gcSHADER Shader,
+    IN gctUINT32 MaxKernelFunctionArgs
+    );
+
+/*******************************************************************************
+**  gcSHADER_AddTypeNameBuffer
+**
+**  add buffer containing all non basic type names of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctSIZE_T TypeNameBufferSize
+**          Type name buffer size in bytes
+**
+**      gctCHAR *TypeNameBuffer
+**          Non basic type names
+*/
+gceSTATUS
+gcSHADER_AddTypeNameBuffer(
+    IN gcSHADER Shader,
+    IN gctUINT32 TypeNameBufferSize,
+    IN gctCHAR * TypeNameBuffer
+    );
+/*******************************************************************************
+**  gcSHADER_SetConstantMemorySize
+**
+**  Set the constant memory address space size of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 ConstantMemorySize
+**          Constant memory size in bytes
+**
+**      gctCHAR *ConstantMemoryBuffer
+**          Constant memory buffer
+*/
+gceSTATUS
+gcSHADER_SetConstantMemorySize(
+    IN gcSHADER Shader,
+    IN gctUINT32 ConstantMemorySize,
+    IN gctCHAR * ConstantMemoryBuffer
+    );
+
+gceSTATUS
+gcSHADER_AddConstantMemorySize(
+    IN gcSHADER Shader,
+    IN gctUINT32 ConstantMemorySize,
+    IN gctCHAR * ConstantMemoryBuffer
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetConstantMemorySize
+**
+**  Set the constant memory address space size of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * ConstantMemorySize
+**          Pointer to a variable receiving constant memory size in bytes
+**
+**      gctCHAR **ConstantMemoryBuffer.
+**          Pointer to a variable for returned shader constant memory buffer.
+*/
+gceSTATUS
+gcSHADER_GetConstantMemorySize(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * ConstantMemorySize,
+    OUT gctCHAR ** ConstantMemoryBuffer
+    );
+
+/*******************************************************************************
+**  gcSHADER_SetPrivateMemorySize
+**
+**  Set the private memory address space size of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 PrivateMemorySize
+**          Private memory size in bytes
+*/
+gceSTATUS
+gcSHADER_SetPrivateMemorySize(
+    IN gcSHADER Shader,
+    IN gctUINT32 PrivateMemorySize
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetPrivateMemorySize
+**
+**  Set the private memory address space size of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * PrivateMemorySize
+**          Pointer to a variable receiving private memory size in bytes
+*/
+gceSTATUS
+gcSHADER_GetPrivateMemorySize(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * PrivateMemorySize
+    );
+
+/*******************************************************************************
+**  gcSHADER_SetLocalMemorySize
+**
+**  Set the local memory address space size of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**      gctUINT32 LocalMemorySize
+**          Local memory size in bytes
+*/
+gceSTATUS
+gcSHADER_SetLocalMemorySize(
+    IN gcSHADER Shader,
+    IN gctUINT32 LocalMemorySize
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetLocalMemorySize
+**
+**  Set the local memory address space size of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * LocalMemorySize
+**          Pointer to a variable receiving lcoal memory size in bytes
+*/
+gceSTATUS
+gcSHADER_GetLocalMemorySize(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * LocalMemorySize
+    );
+
+/*******************************************************************************
+**  gcSHADER_GetWorkGroupSize
+**
+**  Get the workGroupSize of a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * WorkGroupSize
+**          Pointer to a variable receiving workGroupSize
+*/
+gceSTATUS
+gcSHADER_GetWorkGroupSize(
+    IN gcSHADER Shader,
+    OUT gctUINT * WorkGroupSize
+    );
+
+gctINT
+gcSHADER_GetLtcCodeUniformIndex(
+    IN gcSHADER Shader,
+    IN gctUINT CodeIndex
+    );
+
+/*******************************************************************************
+**  gcSHADER_CheckValidity
+**
+**  Check validity for a gcSHADER object.
+**
+**  INPUT:
+**
+**      gcSHADER Shader
+**          Pointer to a gcSHADER object.
+**
+*/
+gceSTATUS
+gcSHADER_CheckValidity(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**                               gcSHADER_GetVariableTempTypes
+********************************************************************************
+**
+**    Get the gcVARIABLE temp types and save the type to TempTypeArray.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcVARIABLE variable
+**            Start variable.
+**
+**        gctUINT TempTypeArraySize
+**            The size of temp type array.
+**
+**    OUTPUT:
+**
+**        gcSHADER_TYPE * TempTypeArray
+**            Pointer to temp type array
+**
+*/
+gceSTATUS
+gcSHADER_GetVariableTempTypes(
+    IN gcSHADER            Shader,
+    IN gcVARIABLE          Variable,
+    IN gctUINT             TempTypeArraySize,
+    IN gctINT              FisrtTempIndex,
+    OUT gcSHADER_TYPE *    TempTypeArray
+    );
+
+gceSTATUS
+gcATTRIBUTE_IsPosition(
+        IN gcATTRIBUTE Attribute,
+        OUT gctBOOL * IsPosition,
+        OUT gctBOOL * IsDirectPosition
+        );
+
+/*******************************************************************************
+**  gcATTRIBUTE_SetPrecision
+**
+**  Set the precision of an attribute.
+**
+**  INPUT:
+**
+**      gcATTRIBUTE Attribute
+**          Pointer to a gcATTRIBUTE object.
+**
+**    gcSHADER_PRECISION Precision
+**          Precision of the attribute.
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcATTRIBUTE_SetPrecision(
+    IN gcATTRIBUTE Attribute,
+    IN gcSHADER_PRECISION Precision
+    );
+
+/*******************************************************************************
+**                             gcATTRIBUTE_GetType
+********************************************************************************
+**
+**    Get the type and array length of a gcATTRIBUTE object.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcATTRIBUTE Attribute
+**            Pointer to a gcATTRIBUTE object.
+**
+**    OUTPUT:
+**
+**        gcSHADER_TYPE * Type
+**            Pointer to a variable receiving the type of the attribute.  'Type'
+**            can be gcvNULL, in which case no type will be returned.
+**
+**        gctUINT32 * ArrayLength
+**            Pointer to a variable receiving the length of the array if the
+**            attribute was declared as an array.  If the attribute was not
+**            declared as an array, the array length will be 1.  'ArrayLength' can
+**            be gcvNULL, in which case no array length will be returned.
+*/
+gceSTATUS
+gcATTRIBUTE_GetType(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    OUT gcSHADER_TYPE * Type,
+    OUT gctUINT32 * ArrayLength
+    );
+
+gceSTATUS
+gcATTRIBUTE_GetLocation(
+    IN gcATTRIBUTE Attribute,
+    OUT gctINT * Location
+    );
+
+gceSTATUS
+gcATTRIBUTE_GetPrecision(
+    IN gcATTRIBUTE Attribute,
+    OUT gcSHADER_PRECISION * Precision
+    );
+
+/*******************************************************************************
+**                            gcATTRIBUTE_GetName
+********************************************************************************
+**
+**    Get the name of a gcATTRIBUTE object.
+**
+**    INPUT:
+**
+**      gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcATTRIBUTE Attribute
+**            Pointer to a gcATTRIBUTE object.
+**
+**        gctBOOL UseInstanceName
+**            Use instance name for a block member.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Length
+**            Pointer to a variable receiving the length of the attribute name.
+**            'Length' can be gcvNULL, in which case no length will be returned.
+**
+**        gctCONST_STRING * Name
+**            Pointer to a variable receiving the pointer to the attribute name.
+**            'Name' can be gcvNULL, in which case no name will be returned.
+*/
+gceSTATUS
+gcATTRIBUTE_GetName(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    IN gctBOOL UseInstanceName,
+    OUT gctUINT32 * Length,
+    OUT gctCONST_STRING * Name
+    );
+
+/*******************************************************************************
+**                            gcATTRIBUTE_GetNameEx
+********************************************************************************
+**
+**    Get the name of a gcATTRIBUTE object.
+**
+**    INPUT:
+**
+**      gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcATTRIBUTE Attribute
+**            Pointer to a gcATTRIBUTE object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Length
+**            Pointer to a variable receiving the length of the attribute name.
+**            'Length' can be gcvNULL, in which case no length will be returned.
+**
+**        gctSTRING * Name
+**            Pointer to a variable receiving the pointer to the attribute name.
+**            'Name' can be gcvNULL, in which case no name will be returned.
+*/
+gceSTATUS
+gcATTRIBUTE_GetNameEx(
+    IN gcSHADER Shader,
+    IN gcATTRIBUTE Attribute,
+    OUT gctUINT32 * Length,
+    OUT gctSTRING * Name
+    );
+
+/*******************************************************************************
+**                            gcATTRIBUTE_IsEnabled
+********************************************************************************
+**
+**    Query the enabled state of a gcATTRIBUTE object.
+**
+**    INPUT:
+**
+**        gcATTRIBUTE Attribute
+**            Pointer to a gcATTRIBUTE object.
+**
+**    OUTPUT:
+**
+**        gctBOOL * Enabled
+**            Pointer to a variable receiving the enabled state of the attribute.
+*/
+gceSTATUS
+gcATTRIBUTE_IsEnabled(
+    IN gcATTRIBUTE Attribute,
+    OUT gctBOOL * Enabled
+    );
+
+gceSTATUS
+gcATTRIBUTE_GetIndex(
+    IN gcATTRIBUTE Attribute,
+    OUT gctUINT16 * Index
+    );
+
+gceSTATUS
+gcATTRIBUTE_IsPerPatch(
+    IN gcATTRIBUTE Attribute,
+    OUT gctBOOL * IsPerPatch
+    );
+
+
+gceSTATUS
+gcATTRIBUTE_IsSample(
+    IN gcATTRIBUTE Attribute,
+    OUT gctBOOL * IsSample
+    );
+
+/*******************************************************************************
+**                              gcUNIFORM_GetType
+********************************************************************************
+**
+**    Get the type and array length of a gcUNIFORM object.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**    OUTPUT:
+**
+**        gcSHADER_TYPE * Type
+**            Pointer to a variable receiving the type of the uniform.  'Type' can
+**            be gcvNULL, in which case no type will be returned.
+**
+**        gctUINT32 * ArrayLength
+**            Pointer to a variable receiving the length of the array if the
+**            uniform was declared as an array.  If the uniform was not declared
+**            as an array, the array length will be 1.  'ArrayLength' can be gcvNULL,
+**            in which case no array length will be returned.
+*/
+gceSTATUS
+gcUNIFORM_GetType(
+    IN gcUNIFORM Uniform,
+    OUT gcSHADER_TYPE * Type,
+    OUT gctUINT32 * ArrayLength
+    );
+
+/*******************************************************************************
+**                              gcUNIFORM_GetTypeEx
+********************************************************************************
+**
+**    Get the type and array length of a gcUNIFORM object.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**    OUTPUT:
+**
+**        gcSHADER_TYPE * Type
+**            Pointer to a variable receiving the type of the uniform.  'Type' can
+**            be gcvNULL, in which case no type will be returned.
+**
+**        gcSHADER_PRECISION * Precision
+**            Pointer to a variable receiving the precision of the uniform.  'Precision' can
+**            be gcvNULL, in which case no type will be returned.
+**
+**        gctUINT32 * ArrayLength
+**            Pointer to a variable receiving the length of the array if the
+**            uniform was declared as an array.  If the uniform was not declared
+**            as an array, the array length will be 1.  'ArrayLength' can be gcvNULL,
+**            in which case no array length will be returned.
+*/
+gceSTATUS
+gcUNIFORM_GetTypeEx(
+    IN gcUNIFORM Uniform,
+    OUT gcSHADER_TYPE * Type,
+    OUT gcSHADER_TYPE_KIND * Category,
+    OUT gcSHADER_PRECISION * Precision,
+    OUT gctUINT32 * ArrayLength
+    );
+
+/*******************************************************************************
+**                              gcUNIFORM_GetFlags
+********************************************************************************
+**
+**    Get the flags of a gcUNIFORM object.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**    OUTPUT:
+**
+**        gceUNIFORM_FLAGS * Flags
+**            Pointer to a variable receiving the flags of the uniform.
+**
+*/
+gceSTATUS
+gcUNIFORM_GetFlags(
+    IN gcUNIFORM Uniform,
+    OUT gceUNIFORM_FLAGS * Flags
+    );
+
+/*******************************************************************************
+**                              gcUNIFORM_SetFlags
+********************************************************************************
+**
+**    Set the flags of a gcUNIFORM object.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**        gceUNIFORM_FLAGS Flags
+**            Flags of the uniform to be set.
+**
+**    OUTPUT:
+**            Nothing.
+**
+*/
+gceSTATUS
+gcUNIFORM_SetFlags(
+    IN gcUNIFORM Uniform,
+    IN gceUNIFORM_FLAGS Flags
+    );
+
+/*******************************************************************************
+**                              gcOUTPUT_SetLayoutQualifier
+********************************************************************************
+**
+**    Set the layout qualifiers of a gcOUTPUT object.
+**
+**    INPUT:
+**
+**        gcOUTPUT Output
+**            Pointer to a gcOUTPUT object.
+**
+**        gceLAYOUT_QUALIFIER LayoutQualifier
+**            Layout qualifier of the output to be set.
+**
+**    OUTPUT:
+**            Nothing.
+**
+*/
+gceSTATUS
+gcOUTPUT_SetLayoutQualifier(
+    IN gcOUTPUT Output,
+    IN gceLAYOUT_QUALIFIER LayoutQualifier
+    );
+
+/*******************************************************************************
+**                              gcOUTPUT_SetLayoutQualifier
+********************************************************************************
+**
+**    Get the layout qualifiers of a gcOUTPUT object.
+**
+**    INPUT:
+**
+**        gcOUTPUT Output
+**            Pointer to a gcOUTPUT object.
+**
+**    OUTPUT:
+**        gceLAYOUT_QUALIFIER *LayoutQualifier
+**            Pointer to a variable receiving the layout qualifier of the output.
+**
+*/
+gceSTATUS
+gcOUTPUT_GetLayoutQualifier(
+    IN gcOUTPUT Output,
+    OUT gceLAYOUT_QUALIFIER * LayoutQualifier
+    );
+
+/*******************************************************************************
+**                              gcUNIFORM_GetName
+********************************************************************************
+**
+**    Get the name of a gcUNIFORM object.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Length
+**            Pointer to a variable receiving the length of the uniform name.
+**            'Length' can be gcvNULL, in which case no length will be returned.
+**
+**        gctCONST_STRING * Name
+**            Pointer to a variable receiving the pointer to the uniform name.
+**            'Name' can be gcvNULL, in which case no name will be returned.
+*/
+gceSTATUS
+gcUNIFORM_GetName(
+    IN gcUNIFORM Uniform,
+    OUT gctUINT32 * Length,
+    OUT gctCONST_STRING * Name
+    );
+
+/*******************************************************************************
+**  gcUNIFORM_BLOCK_GetName
+**
+**  Get the name of a gcsUNIFORM_BLOCK object.
+**
+**  INPUT:
+**
+**      gcsUNIFORM_BLOCK UniformBlock
+**          Pointer to a gcsUNIFORM_BLOCK object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Length
+**          Pointer to a variable receiving the length of the uniform block name.
+**          'Length' can be gcvNULL, in which case no length will be returned.
+**
+**      gctCONST_STRING * Name
+**          Pointer to a variable receiving the pointer to the uniform block name.
+**          'Name' can be gcvNULL, in which case no name will be returned.
+*/
+gceSTATUS
+gcUNIFORM_BLOCK_GetName(
+    IN gcsUNIFORM_BLOCK UniformBlock,
+    OUT gctUINT32 * Length,
+    OUT gctCONST_STRING * Name
+    );
+
+/*******************************************************************************
+**                              gcUNIFORM_GetSampler
+********************************************************************************
+**
+**    Get the physical sampler number for a sampler gcUNIFORM object.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Sampler
+**            Pointer to a variable receiving the physical sampler.
+*/
+gceSTATUS
+gcUNIFORM_GetSampler(
+    IN gcUNIFORM Uniform,
+    OUT gctUINT32 * Sampler
+    );
+
+gceSTATUS
+gcUNIFORM_GetIndex(
+    IN gcUNIFORM Uniform,
+    OUT gctUINT16 * Index
+    );
+
+/*******************************************************************************
+**  gcUNIFORM_GetFormat
+**
+**  Get the type and array length of a gcUNIFORM object.
+**
+**  INPUT:
+**
+**      gcUNIFORM Uniform
+**          Pointer to a gcUNIFORM object.
+**
+**  OUTPUT:
+**
+**      gcSL_FORMAT * Format
+**          Pointer to a variable receiving the format of element of the uniform.
+**          'Type' can be gcvNULL, in which case no type will be returned.
+**
+**      gctBOOL * IsPointer
+**          Pointer to a variable receiving the state wheter the uniform is a pointer.
+**          'IsPointer' can be gcvNULL, in which case no array length will be returned.
+*/
+gceSTATUS
+gcUNIFORM_GetFormat(
+    IN gcUNIFORM Uniform,
+    OUT gcSL_FORMAT * Format,
+    OUT gctBOOL * IsPointer
+    );
+
+/*******************************************************************************
+**  gcUNIFORM_SetFormat
+**
+**  Set the format and isPointer of a uniform.
+**
+**  INPUT:
+**
+**      gcUNIFORM Uniform
+**          Pointer to a gcUNIFORM object.
+**
+**      gcSL_FORMAT Format
+**          Format of element of the uniform shaderType.
+**
+**      gctBOOL IsPointer
+**          Wheter the uniform is a pointer.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gcUNIFORM_SetFormat(
+    IN gcUNIFORM Uniform,
+    IN gcSL_FORMAT Format,
+    IN gctBOOL IsPointer
+    );
+
+/*******************************************************************************
+**                               gcUNIFORM_SetValue
+********************************************************************************
+**
+**    Set the value of a uniform in integer.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**        gctUINT32 Count
+**            Number of entries to program if the uniform has been declared as an
+**            array.
+**
+**        const gctINT * Value
+**            Pointer to a buffer holding the integer values for the uniform.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcUNIFORM_SetValue(
+    IN gcUNIFORM Uniform,
+    IN gctUINT32 Count,
+    IN const gctINT * Value
+    );
+
+gceSTATUS
+gcUNIFORM_SetValue_Ex(
+    IN gcUNIFORM Uniform,
+    IN gctUINT32 Count,
+    IN gcsHINT_PTR Hints,
+    IN const gctINT * Value
+    );
+
+
+/*******************************************************************************
+**                               gcUNIFORM_SetValueF
+********************************************************************************
+**
+**    Set the value of a uniform in floating point.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**        gctUINT32 Count
+**            Number of entries to program if the uniform has been declared as an
+**            array.
+**
+**        const gctFLOAT * Value
+**            Pointer to a buffer holding the floating point values for the
+**            uniform.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gceSTATUS
+gcUNIFORM_SetValueF(
+    IN gcUNIFORM Uniform,
+    IN gctUINT32 Count,
+    IN const gctFLOAT * Value
+    );
+
+gceSTATUS
+gcUNIFORM_SetValueF_Ex(
+    IN gcUNIFORM Uniform,
+    IN gctUINT32 Count,
+    IN gcsHINT_PTR Hints,
+    IN const gctFLOAT * Value
+    );
+
+/*******************************************************************************
+**                         gcUNIFORM_GetModelViewProjMatrix
+********************************************************************************
+**
+**    Get the value of uniform modelViewProjMatrix ID if present.
+**
+**    INPUT:
+**
+**        gcUNIFORM Uniform
+**            Pointer to a gcUNIFORM object.
+**
+**    OUTPUT:
+**
+**        Nothing.
+*/
+gctUINT
+gcUNIFORM_GetModelViewProjMatrix(
+    IN gcUNIFORM Uniform
+    );
+
+/*******************************************************************************
+**                                gcOUTPUT_GetType
+********************************************************************************
+**
+**    Get the type and array length of a gcOUTPUT object.
+**
+**    INPUT:
+**
+**        gcOUTPUT Output
+**            Pointer to a gcOUTPUT object.
+**
+**    OUTPUT:
+**
+**        gcSHADER_TYPE * Type
+**            Pointer to a variable receiving the type of the output.  'Type' can
+**            be gcvNULL, in which case no type will be returned.
+**
+**        gctUINT32 * ArrayLength
+**            Pointer to a variable receiving the length of the array if the
+**            output was declared as an array.  If the output was not declared
+**            as an array, the array length will be 1.  'ArrayLength' can be gcvNULL,
+**            in which case no array length will be returned.
+*/
+gceSTATUS
+gcOUTPUT_GetType(
+    IN gcOUTPUT Output,
+    OUT gcSHADER_TYPE * Type,
+    OUT gctUINT32 * ArrayLength
+    );
+
+/*******************************************************************************
+**                               gcOUTPUT_GetIndex
+********************************************************************************
+**
+**    Get the index of a gcOUTPUT object.
+**
+**    INPUT:
+**
+**        gcOUTPUT Output
+**            Pointer to a gcOUTPUT object.
+**
+**    OUTPUT:
+**
+**        gctUINT * Index
+**            Pointer to a variable receiving the temporary register index of the
+**            output.  'Index' can be gcvNULL,. in which case no index will be
+**            returned.
+*/
+gceSTATUS
+gcOUTPUT_GetIndex(
+    IN gcOUTPUT Output,
+    OUT gctUINT * Index
+    );
+
+/*******************************************************************************
+**                                gcOUTPUT_GetName
+********************************************************************************
+**
+**    Get the name of a gcOUTPUT object.
+**
+**    INPUT:
+**
+**      gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcOUTPUT Output
+**            Pointer to a gcOUTPUT object.
+**
+**        gctBOOL UseInstanceName
+**            Use instance name for a block member.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Length
+**            Pointer to a variable receiving the length of the output name.
+**            'Length' can be gcvNULL, in which case no length will be returned.
+**
+**        gctCONST_STRING * Name
+**            Pointer to a variable receiving the pointer to the output name.
+**            'Name' can be gcvNULL, in which case no name will be returned.
+*/
+gceSTATUS
+gcOUTPUT_GetName(
+    IN gcSHADER Shader,
+    IN gcOUTPUT Output,
+    IN gctBOOL UseInstanceName,
+    OUT gctUINT32 * Length,
+    OUT gctCONST_STRING * Name
+    );
+
+/*******************************************************************************
+**                                gcOUTPUT_GetNameEx
+********************************************************************************
+**
+**    Get the name of a gcOUTPUT object.
+**
+**    INPUT:
+**
+**      gcSHADER Shader
+**            Pointer to a gcSHADER object.
+**
+**        gcOUTPUT Output
+**            Pointer to a gcOUTPUT object.
+**
+**        gctBOOL UseInstanceName
+**            Use instance name for a block member.
+**
+**    OUTPUT:
+**
+**        gctUINT32 * Length
+**            Pointer to a variable receiving the length of the output name.
+**            'Length' can be gcvNULL, in which case no length will be returned.
+**
+**        gctCONST_STRING * Name
+**            Pointer to a variable receiving the pointer to the output name.
+**            'Name' can be gcvNULL, in which case no name will be returned.
+*/
+gceSTATUS
+gcOUTPUT_GetNameEx(
+    IN gcSHADER Shader,
+    IN gcOUTPUT Output,
+    OUT gctUINT32 * Length,
+    OUT gctSTRING * Name
+    );
+
+/*******************************************************************************
+**  gcOUTPUT_GetLocation
+**
+**  Get the Location of a gcOUTPUT object.
+**
+**  INPUT:
+**
+**      gcOUTPUT Output
+**          Pointer to a gcOUTPUT object.
+**
+**  OUTPUT:
+**
+**      gctUINT * Location
+**          Pointer to a variable receiving the Location of the
+**          output.
+*/
+gceSTATUS
+gcOUTPUT_GetLocation(
+    IN gcOUTPUT Output,
+    OUT gctUINT * Location
+    );
+
+
+/*******************************************************************************
+*********************************************************** F U N C T I O N S **
+*******************************************************************************/
+
+/*******************************************************************************
+**  gcFUNCTION_ReallocateArguments
+**
+**  Reallocate an array of gcsFUNCTION_ARGUMENT objects.
+**
+**  INPUT:
+**
+**      gcFUNCTION Function
+**          Pointer to a gcFUNCTION object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcFUNCTION_ReallocateArguments(
+    IN gcFUNCTION Function,
+    IN gctUINT32 Count
+    );
+
+gceSTATUS
+gcFUNCTION_AddArgument(
+    IN gcFUNCTION Function,
+    IN gctUINT16 VariableIndex,
+    IN gctUINT32 TempIndex,
+    IN gctUINT8 Enable,
+    IN gctUINT8 Qualifier,
+    IN gctUINT8 Precision,
+    IN gctBOOL IsPrecise
+    );
+
+gceSTATUS
+gcFUNCTION_GetArgument(
+    IN gcFUNCTION Function,
+    IN gctUINT32 Index,
+    OUT gctUINT32_PTR Temp,
+    OUT gctUINT8_PTR Enable,
+    OUT gctUINT8_PTR Swizzle
+    );
+
+gceSTATUS
+gcFUNCTION_GetLabel(
+    IN gcFUNCTION Function,
+    OUT gctUINT_PTR Label
+    );
+
+/*******************************************************************************
+************************* K E R N E L    P R O P E R T Y    F U N C T I O N S **
+*******************************************************************************/
+/*******************************************************************************/
+gceSTATUS
+gcKERNEL_FUNCTION_AddKernelFunctionProperties(
+        IN gcKERNEL_FUNCTION KernelFunction,
+        IN gctINT propertyType,
+        IN gctUINT32 propertySize,
+        IN gctINT * values
+        );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetPropertyCount(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    OUT gctUINT32 * Count
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetProperty(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctUINT Index,
+    OUT gctUINT32 * propertySize,
+    OUT gctINT * propertyType,
+    OUT gctINT * propertyValues
+    );
+
+
+/*******************************************************************************
+*******************************I M A G E   S A M P L E R    F U N C T I O N S **
+*******************************************************************************/
+/*******************************************************************************
+**  gcKERNEL_FUNCTION_ReallocateImageSamplers
+**
+**  Reallocate an array of pointers to image sampler pair.
+**
+**  INPUT:
+**
+**      gcKERNEL_FUNCTION KernelFunction
+**          Pointer to a gcKERNEL_FUNCTION object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcKERNEL_FUNCTION_ReallocateImageSamplers(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctUINT32 Count
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_AddImageSampler(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctUINT8 ImageNum,
+    IN gctBOOL IsConstantSamplerType,
+    IN gctUINT32 SamplerType
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetImageSamplerCount(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    OUT gctUINT32 * Count
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetImageSampler(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctUINT Index,
+    OUT gctUINT8 *ImageNum,
+    OUT gctBOOL *IsConstantSamplerType,
+    OUT gctUINT32 *SamplerType
+    );
+
+/*******************************************************************************
+*********************************************K E R N E L    F U N C T I O N S **
+*******************************************************************************/
+
+/*******************************************************************************
+**  gcKERNEL_FUNCTION_ReallocateArguments
+**
+**  Reallocate an array of gcsFUNCTION_ARGUMENT objects.
+**
+**  INPUT:
+**
+**      gcKERNEL_FUNCTION Function
+**          Pointer to a gcKERNEL_FUNCTION object.
+**
+**      gctUINT32 Count
+**          Array count to reallocate.  'Count' must be at least 1.
+*/
+gceSTATUS
+gcKERNEL_FUNCTION_ReallocateArguments(
+    IN gcKERNEL_FUNCTION Function,
+    IN gctUINT32 Count
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_AddArgument(
+    IN gcKERNEL_FUNCTION Function,
+    IN gctUINT16 VariableIndex,
+    IN gctUINT32 TempIndex,
+    IN gctUINT8 Enable,
+    IN gctUINT8 Qualifier
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetArgument(
+    IN gcKERNEL_FUNCTION Function,
+    IN gctUINT32 Index,
+    OUT gctUINT32_PTR Temp,
+    OUT gctUINT8_PTR Enable,
+    OUT gctUINT8_PTR Swizzle
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetLabel(
+    IN gcKERNEL_FUNCTION Function,
+    OUT gctUINT_PTR Label
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetName(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    OUT gctUINT32 * Length,
+    OUT gctCONST_STRING * Name
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_ReallocateUniformArguments(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctUINT32 Count
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_AddUniformArgument(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctCONST_STRING Name,
+    IN gcSHADER_TYPE Type,
+    IN gctUINT32 Length,
+    OUT gcUNIFORM * UniformArgument
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetUniformArgumentCount(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    OUT gctUINT32 * Count
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_GetUniformArgument(
+    IN gcKERNEL_FUNCTION KernelFunction,
+    IN gctUINT Index,
+    OUT gcUNIFORM * UniformArgument
+    );
+
+gceSTATUS
+gcKERNEL_FUNCTION_SetCodeEnd(
+    IN gcKERNEL_FUNCTION KernelFunction
+    );
+
+/*******************************************************************************
+**                              gcInitializeCompiler
+********************************************************************************
+**
+**  Initialize compiler global variables.
+**
+**  Input:
+**      gcePATCH_ID PatchId,
+**      patch ID
+**
+**      gcsHWCaps HWCaps,
+**      HW capabilities filled in by driver and passed to compiler
+**
+**      gcsGLSLCaps *Caps
+**      Min/Max capabilities filled in by driver and passed to compiler
+**
+**  Output:
+**      Nothing
+**
+*/
+gceSTATUS
+gcInitializeCompiler(
+    IN gcePATCH_ID PatchId,
+    IN gcsHWCaps *HWCaps,
+    IN gcsGLSLCaps *Caps
+    );
+
+gceSTATUS
+gcInitializeCompilerCaps(
+    IN gcsGLSLCaps *Caps
+    );
+
+/*******************************************************************************
+**                              gcFinalizeCompiler
+********************************************************************************
+**  Finalize compiler global variables.
+**
+**
+**  Output:
+**      Nothing
+**
+*/
+gceSTATUS
+gcFinalizeCompiler(void);
+
+/*******************************************************************************
+**                              gcCompileShader
+********************************************************************************
+**
+**    Compile a shader.
+**
+**    INPUT:
+**
+**        gctINT ShaderType
+**            Shader type to compile.  Can be one of the following values:
+**
+**                gcSHADER_TYPE_VERTEX
+**                    Compile a vertex shader.
+**
+**                gcSHADER_TYPE_FRAGMENT
+**                    Compile a fragment shader.
+**
+**        gctUINT SourceSize
+**            Size of the source buffer in bytes.
+**
+**        gctCONST_STRING Source
+**            Pointer to the buffer containing the shader source code.
+**
+**    OUTPUT:
+**
+**        gcSHADER * Binary
+**            Pointer to a variable receiving the pointer to a gcSHADER object
+**            containg the compiled shader code.
+**
+**        gctSTRING * Log
+**            Pointer to a variable receiving a string pointer containging the
+**            compile log.
+*/
+gceSTATUS
+gcCompileShader(
+    IN gctINT ShaderType,
+    IN gctUINT SourceSize,
+    IN gctCONST_STRING Source,
+    OUT gcSHADER * Binary,
+    OUT gctSTRING * Log
+    );
+
+
+/*******************************************************************************
+**                              gcSetClientApiVersion
+********************************************************************************
+**
+**    Set Client API version
+**
+*/
+gceSTATUS
+gcSetClientApiVersion(
+    IN gceAPI ApiVersion
+    );
+
+/*******************************************************************************
+**                              gcLoadKernelCompiler
+********************************************************************************
+**
+**    OpenCL kernel shader compiler load.
+**
+*/
+gceSTATUS
+gcLoadKernelCompiler(
+    IN gcsHWCaps *HWCaps,
+    IN gcePATCH_ID PatchId
+    );
+
+/*******************************************************************************
+**                              gcOptimizeShader
+********************************************************************************
+**
+**    Optimize a shader.
+**
+**    INPUT:
+**
+**        gcSHADER Shader
+**            Pointer to a gcSHADER object holding information about the compiled
+**            shader.
+**
+**        gctFILE LogFile
+**            Pointer to an open FILE object.
+*/
+gceSTATUS
+gcOptimizeShader(
+    IN gcSHADER Shader,
+    IN gctFILE LogFile
+    );
+
+gceSTATUS
+gcSetUniformShaderKind(
+    IN gcSHADER Shader
+    );
+
+/*******************************************************************************
+**                                gcLinkShaders
+********************************************************************************
+**
+**    Link two shaders and generate a harwdare specific state buffer by compiling
+**    the compiler generated code through the resource allocator and code
+**    generator.
+**
+**    INPUT:
+**
+**        gcSHADER VertexShader
+**            Pointer to a gcSHADER object holding information about the compiled
+**            vertex shader.
+**
+**        gcSHADER FragmentShader
+**            Pointer to a gcSHADER object holding information about the compiled
+**            fragment shader.
+**
+**        gceSHADER_FLAGS Flags
+**            Compiler flags.  Can be any of the following:
+**
+**                gcvSHADER_DEAD_CODE       - Dead code elimination.
+**                gcvSHADER_RESOURCE_USAGE  - Resource usage optimizaion.
+**                gcvSHADER_OPTIMIZER       - Full optimization.
+**                gcvSHADER_USE_GL_Z        - Use OpenGL ES Z coordinate.
+**                gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
+**                gcvSHADER_USE_GL_FACE     - Use OpenGL ES gl_FaceForward.
+**
+**    OUTPUT:
+**
+**        gcsPROGRAM_STATE *ProgramState
+**            Pointer to a variable receicing the program state.
+*/
+gceSTATUS
+gcLinkShaders(
+    IN gcSHADER VertexShader,
+    IN gcSHADER FragmentShader,
+    IN gceSHADER_FLAGS Flags,
+    IN OUT gcsPROGRAM_STATE *ProgramState
+    );
+
+
+
+/*******************************************************************************************
+**  Initialize libfile
+*/
+gceSTATUS
+gcInitializeLibFile(void);
+
+/*******************************************************************************************
+**  Finalize libfile.
+**
+*/
+gceSTATUS
+gcFinalizeLibFile(void);
+
+
+
+/*******************************************************************************
+**                                gcSHADER_WriteShaderToFile
+********************************************************************************
+**
+**    write user shader info into file
+**
+**    INPUT:
+**
+**        gcSHADER    Binary,
+**            Pointer to a gcSHADER object holding information about the shader
+**
+**        gctSTRING    ShaderName
+**            Pointer to a gcSHADER name
+**
+**    OUTPUT:none
+**
+*/
+gceSTATUS
+gcSHADER_WriteShaderToFile(
+    IN gcSHADER    Binary,
+    IN gctSTRING    ShaderName
+    );
+/*******************************************************************************
+**                                gcSHADER_ReadShaderFromFile
+********************************************************************************
+**
+**    read user shader info from file
+**
+**    INPUT:
+**        gctSTRING    ShaderName
+**            Pointer to a gcSHADER name
+**
+**
+**    OUTPUT:
+**        gcSHADER    Binary,
+**            Pointer to a gcSHADER object holding information about the shader
+**
+
+**
+*/
+gceSTATUS
+gcSHADER_ReadShaderFromFile(
+    IN gctSTRING    ShaderName,
+    OUT gcSHADER    *Binary
+    );
+
+/*******************************************************************************
+**                                gcLinkProgram
+********************************************************************************
+**
+**    Link a list shader and generate a hardware specific state buffer by compiling
+**    the compiler generated code through the resource allocator and code
+**    generator.
+**
+**    INPUT:
+**        gctINT ShaderCount
+**            number of gcSHADER object in the shader array
+**
+**        gcSHADER *ShaderArray
+**            Array of gcSHADER object holding information about the compiled
+**            shader.
+**
+**        gceSHADER_FLAGS Flags
+**            Compiler flags.  Can be any of the following:
+**
+**                gcvSHADER_DEAD_CODE       - Dead code elimination.
+**                gcvSHADER_RESOURCE_USAGE  - Resource usage optimizaion.
+**                gcvSHADER_OPTIMIZER       - Full optimization.
+**
+**          gcvSHADER_LOADTIME_OPTIMZATION is set if load-time optimizaiton
+**          is needed
+**
+**    OUTPUT:
+**
+**        gcsPROGRAM_STATE *ProgramState
+**            Pointer to a variable receiving the program state.
+*/
+gceSTATUS
+gcLinkProgram(
+    IN gctINT               ShaderCount,
+    IN gcSHADER *           ShaderArray,
+    IN gceSHADER_FLAGS      Flags,
+    IN gceSHADER_SUB_FLAGS  *SubFlags,
+    IN OUT gcsPROGRAM_STATE *ProgramState
+    );
+
+
+/*******************************************************************************
+**                                gcLinkProgramPipeline
+********************************************************************************
+**
+**    Link a list shader and generate a hardware specific state buffer without any
+**    optimization
+**
+**    INPUT:
+**        gctINT ShaderCount
+**            number of gcSHADER object in the shader array
+**
+**        gcSHADER *ShaderArray
+**            Array of gcSHADER object holding information about the compiled
+**            shader.
+**
+**    OUTPUT:
+**
+**        gcsPROGRAM_STATE *ProgramState
+**            Pointer to a variable receiving the program state.
+*/
+gceSTATUS
+gcLinkProgramPipeline(
+    IN gctINT               ShaderCount,
+    IN gcSHADER *           ShaderArray,
+    IN OUT gcsPROGRAM_STATE *ProgramState
+    );
+
+/*******************************************************************************
+**                                gcValidateProgramPipeline
+********************************************************************************
+**
+**    Validate program pipeline.
+**
+**    INPUT:
+**        gctINT ShaderCount
+**            number of gcSHADER object in the shader array
+**
+**        gcSHADER *ShaderArray
+**            Array of gcSHADER object holding information about the compiled
+**            shader.
+**
+*/
+gceSTATUS
+gcValidateProgramPipeline(
+    IN gctINT               ShaderCount,
+    IN gcSHADER *           ShaderArray
+    );
+
+/* dynamic patch functions */
+/* utility function to constuct patch info */
+
+/* create a format covertion directive with specified sampler name
+ * and sampler info, *PatchDirectivePtr must point to NULL at the
+ * first to this routine, each subsequent call to this routine create
+ *  a new directive and link with the previous one
+ *
+ *  Multiple-Layer support:
+ *    for some format, it is splited to multiple layers, the  SplitLayers
+ *    is the extra layers it splits to, 0 means no extra layer to split,
+ *    the multi-layer sampler uniform will be created later when doing
+ *    dynmaic shader patch, and the driver need to  bind the split
+ *    multi-layer texture objects to the multi-layer sampler uniforms
+ */
+gceSTATUS
+gcCreateInputConversionDirective(
+    IN gcUNIFORM               Sampler,
+    IN gctINT                  ArrayIndex,
+    IN gcsSURF_FORMAT_INFO_PTR FormatInfo,
+    IN gceTEXTURE_SWIZZLE *    Swizzle,
+    IN gctUINT                 Layers,
+    IN gcTEXTURE_MODE          MipFilter,
+    IN gcTEXTURE_MODE          MagFilter,
+    IN gcTEXTURE_MODE          MinFilter,
+    IN gctFLOAT                LODBias,
+    IN gctINT                  Projected,
+    IN gctINT                  Width,
+    IN gctINT                  Height,
+    IN gctINT                  Depth,
+    IN gctINT                  Dimension,
+    IN gctINT                  MipLevelMax,
+    IN gctINT                  MipLevelMin,
+    IN gctBOOL                 SRGB,
+    IN gctBOOL                 AppendToLast,
+    IN gctBOOL                 DepthStencilMode,
+    IN gctBOOL                 NeedFormatConvert,
+    IN gcSHADER_KIND           ShaderKind,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateOutputConversionDirective(
+    IN gctINT                  OutputLocation,
+    IN gcsSURF_FORMAT_INFO_PTR FormatInfo,
+    IN gctUINT                 Layers,
+    IN gctBOOL                 AppendToLast,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateDepthComparisonDirective(
+    IN gcsSURF_FORMAT_INFO_PTR SamplerInfo,
+    IN gcUNIFORM               Sampler,
+    IN gctINT                  ArrayIndex,
+    IN gctUINT                 CompMode,
+    IN gctUINT                 CompFunction,
+    OUT gcPatchDirective **    PatchDirectivePtr
+    );
+
+gceSTATUS
+gcIsSameDepthComparisonDirectiveExist(
+    IN gcsSURF_FORMAT_INFO_PTR SamplerInfo,
+    IN gcUNIFORM               Sampler,
+    IN gctINT                  ArrayIndex,
+    IN gctUINT                 CompMode,
+    IN gctUINT                 CompFunction,
+    IN gcPatchDirective *      PatchDirectivePtr
+    );
+
+gceSTATUS
+gcIsSameInputDirectiveExist(
+    IN gcUNIFORM               Sampler,
+    IN gctINT                  ArrayIndex,
+    IN gcPatchDirective *      PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateColorFactoringDirective(
+    IN gctINT                  RenderTagets,
+    IN gctINT                  FactorCount,
+    IN gctFLOAT *              FactorValue,
+    IN gctBOOL                 AppendToLast,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateAlphaBlendingDirective(
+    IN gctINT                  OutputLocation,
+    IN gctBOOL                 AppendToLast,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateDepthBiasDirective(
+    OUT gcPatchDirective  **   PatchDirectivePtr
+);
+
+gceSTATUS
+gcCreateNP2TextureDirective(
+    IN gctINT TextureCount,
+    IN gcNPOT_PATCH_PARAM_PTR NP2Texture,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateGlobalWorkSizeDirective(
+    IN gcUNIFORM                GlobalWidth,
+    IN gcUNIFORM                GroupWidth,
+    IN gctBOOL                  PatchRealGlobalWorkSize,
+    OUT gcPatchDirective  **    PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateReadImageDirective(
+    IN gctUINT                  SamplerNum,
+    IN gctUINT                  ImageDataIndex,
+    IN gctUINT                  ImageSizeIndex,
+    IN gctUINT                  SamplerValue,
+    IN gctUINT                  ChannelDataType,
+    IN gctUINT                  ChannelOrder,
+    IN gctUINT                  ImageType,
+    OUT gcPatchDirective  **    PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateWriteImageDirective(
+    IN gctUINT                  SamplerNum,
+    IN gctUINT                  ImageDataIndex,
+    IN gctUINT                  ImageSizeIndex,
+    IN gctUINT                  ChannelDataType,
+    IN gctUINT                  ChannelOrder,
+    IN gctUINT                  ImageType,
+    OUT gcPatchDirective  **    PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateCLLongULongDirective(
+    IN  gctUINT                 InstructionIndex,
+    IN  gctUINT                 ChannelCount,
+    OUT gcPatchDirective  **    PatchDirectivePtr
+);
+
+gceSTATUS
+gcCreateRemoveAssignmentForAlphaChannel(
+    IN gctBOOL *               RemoveOutputAlpha,
+    IN gctUINT                 OutputCount,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateYFlippedShaderDirective(
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateSampleMaskDirective(
+    IN gctBOOL                 AlphaToConverageEnabled,
+    IN gctBOOL                 SampleConverageEnabled,
+    IN gctBOOL                 SampleMaskEnabled,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateSignExtent(
+    IN gcUNIFORM               Uniform,
+    IN gctUINT16               ArrayIndex,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateTcsInputMismatch(
+    IN  gctINT                  InputCount,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateColorKillDirective(
+    IN gctFLOAT                Value,
+    OUT gcPatchDirective  **   PatchDirectivePtr
+    );
+
+gceSTATUS
+gcCreateAlphaBlendDirective(
+IN  gctINT                 OutputLocation,
+OUT gcPatchDirective  **   PatchDirectivePtr
+);
+
+gceSTATUS
+gcDestroyPatchDirective(
+    IN OUT gcPatchDirective **  PatchDirectivePtr
+    );
+
+gceSTATUS
+gcLoadCLPatchLibrary(
+    IN gcSHADER   Shader,
+    IN gctUINT    LibIndex
+    );
+
+gceSTATUS
+gcFreeCLPatchLibrary(
+    void
+    );
+
+/* Query samplers ids for PrimarySamplerID in PatchDirectivePtr
+ * if found PrimarySamplerID in the directive, return layers
+ * in *Layers, all sampler id (physical) in SamplersID
+ */
+gceSTATUS
+gcQueryFormatConvertionDirectiveSampler(
+    IN   gcPatchDirective *   PatchDirectivePtr,
+    IN   gcUNIFORM            Sampler,
+    IN   gctINT               ArrayIndex,
+    IN   gctUINT              SamplerBaseOffset,
+    OUT  gctUINT *            SamplersID,
+    OUT  gctUINT *            Layers,
+    OUT  gctBOOL *            Swizzled
+    );
+
+/* Query compiler generated output locations for PrimaryOutputLocation
+ * in PatchDirectivePtr, if PrimaryOutputLocation is found in the directive,
+ * return layers in *Layers, all outputs location in OutputsLocation
+ */
+gceSTATUS
+gcQueryOutputConversionDirective(
+    IN   gcPatchDirective *   PatchDirectivePtr,
+    IN   gctUINT              PrimaryOutputLocation,
+    OUT  gctUINT *            OutputsLocation,
+    OUT  gctUINT *            Layers
+    );
+
+gceSTATUS gcLockLoadLibrary(void);
+gceSTATUS gcUnLockLoadLibrary(void);
+/*******************************************************************************************
+**  Initialize recompilation
+*/
+gceSTATUS
+gcInitializeRecompilation(void);
+
+/*******************************************************************************************
+**  Finalize recompilation.
+**
+*/
+gceSTATUS
+gcFinalizeRecompilation(void);
+
+/* dynamic patch shader */
+gceSTATUS gcSHADER_DynamicPatch(
+    IN OUT gcSHADER         Shader,
+    IN gcPatchDirective  *  PatchDirective,
+    IN gctUINT              isScalar
+    );
+
+/*******************************************************************************
+**                                gcSaveGraphicsProgram
+********************************************************************************
+**
+**  Save pre-compiled shaders and pre-linked programs to a binary file.
+**
+**  INPUT:
+**
+**      gcSHADER* GraphicsShaders
+**          Pointer to graphics shader object.
+**
+**      gcsPROGRAM_STATE ProgramState
+**          Pointer to program state buffer.
+**
+**  OUTPUT:
+**
+**      gctPOINTER * Binary
+**          Pointer to a variable receiving the binary data to be saved.
+**
+**      gctUINT32 * BinarySize
+**          Pointer to a variable receiving the number of bytes inside 'Binary'.
+*/
+gceSTATUS
+gcSaveGraphicsProgram(
+    IN gcSHADER* GraphicsShaders,
+    IN gcsPROGRAM_STATE ProgramState,
+    OUT gctPOINTER * Binary,
+    OUT gctUINT32 * BinarySize
+    );
+
+/*******************************************************************************
+**                                gcSaveComputeProgram
+********************************************************************************
+**
+**    Save pre-compiled shaders and pre-linked programs to a binary file.
+**
+**    INPUT:
+**
+**        gcSHADER ComputeShader
+**            Pointer to compute shader object.
+**
+**        gcsPROGRAM_STATE ProgramState
+**            Program state.
+**
+**    OUTPUT:
+**
+**        gctPOINTER * Binary
+**            Pointer to a variable receiving the binary data to be saved.
+**
+**        gctUINT32 * BinarySize
+**            Pointer to a variable receiving the number of bytes inside 'Binary'.
+*/
+gceSTATUS
+gcSaveComputeProgram(
+    IN gcSHADER ComputeShader,
+    IN gcsPROGRAM_STATE ProgramState,
+    OUT gctPOINTER * Binary,
+    OUT gctUINT32 * BinarySize
+    );
+
+/*******************************************************************************
+**                                gcSaveCLSingleKerne
+********************************************************************************
+**
+**    Save pre-compiled shaders and pre-linked programs to a binary file.
+**
+**    INPUT:
+**
+**        gcSHADER KernelShader
+**            Pointer to vertex shader object.
+**
+**        gcsPROGRAM_STATE ProgramState
+**            Program state.
+**
+**    OUTPUT:
+**
+**        gctPOINTER * Binary
+**            Pointer to a variable receiving the binary data to be saved.
+**
+**        gctUINT32 * BinarySize
+**            Pointer to a variable receiving the number of bytes inside 'Binary'.
+*/
+
+gceSTATUS
+gcSaveCLSingleKernel(
+    IN gcSHADER KernelShader,
+    IN gcsPROGRAM_STATE ProgramState,
+    OUT gctPOINTER * Binary,
+    OUT gctUINT32 * BinarySize
+    );
+
+
+/*******************************************************************************
+**                                gcLoadGraphicsProgram
+********************************************************************************
+**
+**    Load pre-compiled shaders and pre-linked programs from a binary file.
+**
+**    INPUT:
+**
+**        gctPOINTER Binary
+**            Pointer to the binary data loaded.
+**
+**        gctUINT32 BinarySize
+**            Number of bytes in 'Binary'.
+**
+**    OUTPUT:
+**
+**      gcSHADER* GraphicsShaders
+**          Pointer to graphics shader object.
+**
+**        gcsPROGRAM_STATE *ProgramState
+**            Pointer to a variable receicing the program state.
+*/
+gceSTATUS
+gcLoadGraphicsProgram(
+    IN gctPOINTER Binary,
+    IN gctUINT32 BinarySize,
+    IN OUT gcSHADER* GraphicsShaders,
+    IN OUT gcsPROGRAM_STATE *ProgramState
+    );
+
+/*******************************************************************************
+**                                gcLoadComputeProgram
+********************************************************************************
+**
+**    Load pre-compiled shaders and pre-linked programs from a binary file.
+**
+**    INPUT:
+**
+**        gctPOINTER Binary
+**            Pointer to the binary data loaded.
+**
+**        gctUINT32 BinarySize
+**            Number of bytes in 'Binary'.
+**
+**    OUTPUT:
+**
+**        gcSHADER ComputeShader
+**            Pointer to a compute shader object.
+**
+**        gcsPROGRAM_STATE *ProgramState
+**            Pointer to a variable receicing the program state.
+*/
+gceSTATUS
+gcLoadComputeProgram(
+    IN gctPOINTER Binary,
+    IN gctUINT32 BinarySize,
+    OUT gcSHADER ComputeShader,
+    IN OUT gcsPROGRAM_STATE *ProgramState
+    );
+
+/*******************************************************************************
+**                                gcLoadCLSingleKernel
+********************************************************************************
+**
+**    Load pre-compiled shaders and pre-linked programs from a binary file.
+**
+**    INPUT:
+**
+**        gctPOINTER Binary
+**            Pointer to the binary data loaded.
+**
+**        gctUINT32 BinarySize
+**            Number of bytes in 'Binary'.
+**
+**    OUTPUT:
+**
+**        gcSHADER KernelShader
+**            Pointer to a vertex shader object.
+**
+**        gcsPROGRAM_STATE *ProgramState
+**            Pointer to a variable receicing the program state.
+*/
+gceSTATUS
+gcLoadCLSingleKernel(
+    IN gctPOINTER Binary,
+    IN gctUINT32 BinarySize,
+    OUT gcSHADER KernelShader,
+    IN OUT gcsPROGRAM_STATE *ProgramState
+    );
+
+/*******************************************************************************
+**                              gcCompileKernel
+********************************************************************************
+**
+**    Compile a OpenCL kernel shader.
+**
+**    INPUT:
+**
+**        gcoOS Hal
+**            Pointer to an gcoHAL object.
+**
+**        gctUINT SourceSize
+**            Size of the source buffer in bytes.
+**
+**        gctCONST_STRING Source
+**            Pointer to the buffer containing the shader source code.
+**
+**    OUTPUT:
+**
+**        gcSHADER * Binary
+**            Pointer to a variable receiving the pointer to a gcSHADER object
+**            containg the compiled shader code.
+**
+**        gctSTRING * Log
+**            Pointer to a variable receiving a string pointer containging the
+**            compile log.
+*/
+gceSTATUS
+gcCompileKernel(
+    IN gcoHAL Hal,
+    IN gctUINT SourceSize,
+    IN gctCONST_STRING Source,
+    IN gctCONST_STRING Options,
+    OUT gcSHADER * Binary,
+    OUT gctSTRING * Log
+    );
+
+/*******************************************************************************
+**                              gcCLCompileProgram
+********************************************************************************
+**
+**    Compile a OpenCL kernel program as in clCompileProgram().
+**
+**    INPUT:
+**
+**        gcoOS Hal
+**            Pointer to an gcoHAL object.
+**
+**        gctUINT SourceSize
+**            Size of the source buffer in bytes.
+**
+**        gctCONST_STRING Source
+**            Pointer to the buffer containing the shader source code.
+**
+**        gctCONST_STRING Options
+**            Pointer to the buffer containing the compiler options.
+**
+**        gctUINT NumInputHeaders
+**            Number of embedded input headers.
+**
+**        gctCONST_STRING *InputHeaders
+**            Array of pointers to the embedded header sources.
+**
+**        gctCONST_STRING *HeaderIncludeNames
+**            Array of pointers to the header include names.
+**
+**    OUTPUT:
+**
+**        gcSHADER * Binary
+**            Pointer to a variable receiving the pointer to a gcSHADER object
+**            containg the compiled shader code.
+**
+**        gctSTRING * Log
+**            Pointer to a variable receiving a string pointer containging the
+**            compile log.
+*/
+gceSTATUS
+gcCLCompileProgram(
+    IN gcoHAL Hal,
+    IN gctUINT SourceSize,
+    IN gctCONST_STRING Source,
+    IN gctCONST_STRING Options,
+    IN gctUINT NumInputHeaders,
+    IN gctCONST_STRING *InputHeaders,
+    IN gctCONST_STRING *HeaderIncludeNames,
+    OUT gcSHADER * Binary,
+    OUT gctSTRING * Log
+    );
+
+/*******************************************************************************
+**                                gcLinkKernel
+********************************************************************************
+**
+**    Link OpenCL kernel and generate a harwdare specific state buffer by compiling
+**    the compiler generated code through the resource allocator and code
+**    generator.
+**
+**    INPUT:
+**
+**        gcSHADER Kernel
+**            Pointer to a gcSHADER object holding information about the compiled
+**            OpenCL kernel.
+**
+**        gceSHADER_FLAGS Flags
+**            Compiler flags.  Can be any of the following:
+**
+**                gcvSHADER_DEAD_CODE       - Dead code elimination.
+**                gcvSHADER_RESOURCE_USAGE  - Resource usage optimizaion.
+**                gcvSHADER_OPTIMIZER       - Full optimization.
+**                gcvSHADER_USE_GL_Z        - Use OpenGL ES Z coordinate.
+**                gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
+**                gcvSHADER_USE_GL_FACE     - Use OpenGL ES gl_FaceForward.
+**
+**    OUTPUT:
+**
+**        gcsPROGRAM_STATE *ProgramState
+**            Pointer to a variable receiving the program states.
+*/
+gceSTATUS
+gcLinkKernel(
+    IN gcSHADER Kernel,
+    IN gceSHADER_FLAGS Flags,
+    OUT gcsPROGRAM_STATE *ProgramState
+    );
+
+void
+gcTYPE_GetTypeInfo(
+    IN gcSHADER_TYPE      Type,
+    OUT gctUINT32 *       Components,
+    OUT gctUINT32 *       Rows,
+    OUT gctCONST_STRING * Name
+    );
+
+gctBOOL
+gcTYPE_IsTypePacked(
+    IN gcSHADER_TYPE      Type
+    );
+
+void
+gcTYPE_GetFormatInfo(
+    IN  gcSL_FORMAT       ElemFormat,
+    IN  gctUINT32         Components,
+    OUT gctUINT32 *       Rows,
+    OUT gcSHADER_TYPE *   Type
+    );
+
+gcSHADER_TYPE
+gcGetShaderTypeFromFormatAndComponentCount(
+    IN gcSL_FORMAT  ElemFormat,
+    IN gctINT       ComponentCount,
+    IN gctINT       RowCount
+    );
+
+gceSTATUS
+gcSHADER_SetTransformFeedbackVarying(
+    IN gcSHADER Shader,
+    IN gctUINT32 Count,
+    IN gctCONST_STRING *Varyings,
+    IN gceFEEDBACK_BUFFER_MODE BufferMode
+    );
+
+gceSTATUS
+gcSHADER_GetTransformFeedbackVaryingCount(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Count
+    );
+
+gceSTATUS
+gcSHADER_GetTransformFeedbackVarying(
+    IN gcSHADER Shader,
+    IN gctUINT32 Index,
+    OUT gctCONST_STRING * Name,
+    OUT gctUINT *  Length,
+    OUT gcSHADER_TYPE * Type,
+    OUT gctBOOL * IsArray,
+    OUT gctUINT * Size
+    );
+
+gceSTATUS
+gcSHADER_GetTransformFeedbackVaryingStride(
+    IN gcSHADER Shader,
+    OUT gctUINT32 * Stride
+    );
+
+gceSTATUS
+gcSHADER_GetTransformFeedbackVaryingStrideSeparate(
+    IN gcSHADER Shader,
+    IN gctUINT VaryingIndex,
+    OUT gctUINT32 * Stride
+    );
+
+gceSTATUS
+gcSHADER_FreeRecompilerLibrary(
+    void
+    );
+
+gceSTATUS
+gcSHADER_FreeBlendLibrary(
+void
+);
+
+gceSTATUS
+gcSHADER_InsertList(
+    IN gcSHADER                    Shader,
+    IN gcSHADER_LIST *             Root,
+    IN gctINT                      Index,
+    IN gctINT                      Data0,
+    IN gctINT                      Data1
+    );
+
+gceSTATUS
+gcSHADER_UpdateList(
+    IN gcSHADER                    Shader,
+    IN gcSHADER_LIST               Root,
+    IN gctINT                      Index,
+    IN gctINT                      NewIndex
+    );
+
+gceSTATUS
+gcSHADER_DeleteList(
+    IN gcSHADER                    Shader,
+    IN gcSHADER_LIST *             Root,
+    IN gctINT                      Index
+    );
+
+gceSTATUS
+gcSHADER_FindList(
+    IN gcSHADER                    Shader,
+    IN gcSHADER_LIST               Root,
+    IN gctINT                      Index,
+    IN gcSHADER_LIST *             List
+    );
+
+gceSTATUS
+gcSHADER_FindListByData(
+    IN gcSHADER                    Shader,
+    IN gcSHADER_LIST               Root,
+    IN gctINT                      Data0,
+    IN gctINT                      Data1,
+    IN gcSHADER_LIST *             List
+    );
+
+gceSTATUS
+gcSHADER_SetEarlyFragTest(
+    IN gcSHADER                    Shader,
+    IN gctBOOL                     UseEarlyFragTest
+    );
+
+gceSTATUS
+gcSHADER_GetEarlyFragTest(
+    IN gcSHADER                    Shader,
+    IN gctBOOL *                   UseEarlyFragTest
+    );
+
+gceSTATUS
+gcSHADER_GetInstructionCount(
+    IN gcSHADER                    Shader,
+    IN gctUINT *                   InstructionCount
+    );
+
+gceSTATUS
+gcSHADER_QueryValueOrder(
+    IN gcSHADER                    Shader,
+    OUT gctUINT_PTR                ValueOrder
+    );
+
+gceSTATUS
+gcSHADER_GetTCSPatchOutputVertices(
+    IN  gcSHADER                    Shader,
+    OUT gctINT *                    TCSPatchOutputVertices
+    );
+
+gceSTATUS
+gcSHADER_GetTCSPatchInputVertices(
+    IN  gcSHADER                    Shader,
+    OUT gctINT *                    TCSPatchInputVertices
+    );
+
+gceSTATUS
+gcSHADER_GetTCSInputVerticesUniform(
+    IN  gcSHADER                    Shader,
+    OUT gcUNIFORM *                 TCSInputVerticesUniform
+    );
+
+gceSTATUS
+gcSHADER_GetTESPrimitiveMode(
+    IN  gcSHADER                    Shader,
+    OUT gcTessPrimitiveMode *       TESPrimitiveMode
+    );
+
+gceSTATUS
+gcSHADER_GetTESVertexSpacing(
+    IN  gcSHADER                    Shader,
+    OUT gcTessVertexSpacing *       TESVertexSpacing
+    );
+
+gceSTATUS
+gcSHADER_GetTESOrdering(
+    IN  gcSHADER                    Shader,
+    OUT gcTessOrdering *            TESOrdering
+    );
+
+gceSTATUS
+gcSHADER_GetTESPointMode(
+    IN  gcSHADER                    Shader,
+    OUT gctBOOL *                   TESPointMode
+    );
+
+gceSTATUS
+gcSHADER_GetTESPatchInputVertices(
+    IN  gcSHADER                    Shader,
+    OUT gctINT *                    TESPatchInputVertices
+    );
+
+gceSTATUS
+gcSHADER_GetGSLayout(
+    IN  gcSHADER                    Shader,
+    OUT gcGEOLayout *               Layout
+    );
+
+gceSTATUS
+gcSHADER_InsertNOP2BeforeCode(
+    IN OUT gcSHADER                 Shader,
+    OUT gctUINT                     CodeIndex,
+    OUT gctUINT                     AddCodeCount,
+    IN  gctBOOL                     ReplaceJmp,
+    IN  gctBOOL                     MergeWithCodeIndexFunc
+    );
+
+gceSTATUS
+gcSHADER_MoveCodeListBeforeCode(
+    IN OUT gcSHADER                 Shader,
+    IN  gctUINT                     CodeIndex,
+    IN  gctUINT                     CodeHead,
+    IN  gctUINT                     CodeTail
+    );
+
+gceSTATUS
+gcSHADER_ComputeTotalFeedbackVaryingsSize(
+    IN gcSHADER                    VertexShader
+    );
+
+gceSTATUS
+gcSHADER_GetNotStagesRelatedLinkError(
+    IN gcSHADER                    Shader,
+    OUT gceSTATUS *                NotStagesRelatedLinkError
+    );
+
+gceSTATUS
+gcSHADER_SetNotStagesRelatedLinkError(
+    IN gcSHADER                    Shader,
+    IN gceSTATUS                   NotStagesRelatedLinkError
+    );
+
+gceSTATUS
+gcSHADER_Has64BitOperation(
+    IN gcSHADER                    Shader
+    );
+
+void
+gcSHADER_SetDebugInfo(
+    IN gcSHADER             Shader,
+    IN void *                DebugInfoContext
+    );
+
+gctPOINTER
+gcSHADER_GetDebugInfo(
+    IN gcSHADER             Shader
+    );
+
+void
+gcSHADER_SetFragOutUsage(
+    IN gcSHADER             Shader,
+    IN gctUINT              Usage
+    );
+
+gceSTATUS
+gcSHADER_SetAttrLocationByDriver(
+    IN gcSHADER             Shader,
+    IN gctCHAR*             Name,
+    IN gctINT               Location
+    );
+
+gctBOOL
+gceLAYOUT_QUALIFIER_HasHWNotSupportingBlendMode(
+    IN gceLAYOUT_QUALIFIER         Qualifier
+    );
+
+/* return the unsized array variable for StorageBlock
+ * if it's last block member the unsized array variable is returned
+ * otherwise NULL
+ */
+gcVARIABLE
+gcGetSBLastVariable(
+    IN gcSHADER          Shader,
+    IN gcsSTORAGE_BLOCK  StorageBlock
+    );
+
+/* return unsized array leng for StorageBlock in *UnsizedArrayLength
+ * if it's last block member is unsized array variable
+ * otherwise return status = gcvSTATUS_INVALID_REQUEST, and length set to 0
+ */
+gceSTATUS
+gcGetSBUnsizedArrayLength(
+    IN gcSHADER          Shader,
+    IN gcsSTORAGE_BLOCK  StorageBlock,
+    IN gctINT            TotalSizeInBytes,
+    OUT gctINT *         UnsizedArrayLength
+    );
+
+gctBOOL
+gcIsSBUnsized(
+    IN gcsSTORAGE_BLOCK  StorageBlock
+    );
+
+gctUINT
+gcHINTS_GetSamplerBaseOffset(
+    IN gcsHINT_PTR Hints,
+    IN gcSHADER Shader
+    );
+
+gceSTATUS
+gcHINTS_Destroy(
+    IN gcsHINT_PTR Hints
+    );
+
+gctINT
+gcSL_GetName(
+    IN gctUINT32 Length,
+    IN gctCONST_STRING Name,
+    OUT char * Buffer,
+    gctUINT32 BufferSize
+    );
+
+gctUINT8
+gcSL_ConvertSwizzle2Enable(
+    IN gcSL_SWIZZLE X,
+    IN gcSL_SWIZZLE Y,
+    IN gcSL_SWIZZLE Z,
+    IN gcSL_SWIZZLE W
+    );
+
+gceSTATUS
+gcFreeProgramState(
+    IN gcsPROGRAM_STATE ProgramState
+    );
+
+/* dump instruction to stdout */
+void dbg_dumpIR(gcSL_INSTRUCTION Inst,gctINT n);
+
+END_EXTERN_C()
+
+#endif /* __gc_vsc_old_drvi_interface_h_ */
+
diff --git a/drivers/amlogic/npu/inc/old_impl/gc_vsc_old_gcsl.h b/drivers/amlogic/npu/inc/old_impl/gc_vsc_old_gcsl.h
new file mode 100644 (file)
index 0000000..722e3fd
--- /dev/null
@@ -0,0 +1,4886 @@
+/****************************************************************************
+*
+*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
+*
+*    The material in this file is confidential and contains trade secrets
+*    of Vivante Corporation. This is proprietary information owned by
+*    Vivante Corporation. No part of this work may be disclosed,
+*    reproduced, copied, transmitted, or used in any way for any purpose,
+*    without the express written permission of Vivante Corporation.
+*
+*****************************************************************************/
+
+
+/*
+** gcSL language definition
+*/
+
+#ifndef __gc_vsc_old_gcsl_h_
+#define __gc_vsc_old_gcsl_h_
+
+BEGIN_EXTERN_C()
+
+/* always set SHADER_64BITMODE to 0 to unify 32bit and 64bit shader binaries */
+#if (PTRDIFF_MAX  == INT32_MAX)
+#define SHADER_64BITMODE  0
+#else
+#define SHADER_64BITMODE  0
+#endif
+
+#if gcdRENDER_QUALITY_CHECK
+#define TEMP_OPT_CONSTANT_TEXLD_COORD    0
+#else
+#define TEMP_OPT_CONSTANT_TEXLD_COORD    1
+#endif
+
+/******************************* IR VERSION ******************/
+#define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1')
+
+/******************************* SHADER BINARY FILE VERSION ******************/
+/* the shader file version before Loadtime Constant optimization */
+#define gcdSL_SHADER_BINARY_BEFORE_LTC_FILE_VERSION gcmCC(0, 0, 1, 1)
+
+/* bump up version to 1.2 for Loadtime Constant optimization on 1/3/2012 */
+#define gcdSL_SHADER_BINARY_BEFORE_STRUCT_SYMBOL_FILE_VERSION gcmCC(0, 0, 1, 2)
+
+/* bump up version to 1.3 for struct support for variable and uniform on 3/9/2012 */
+#define gcdSL_SHADER_BINARY_BEFORE_VARIABLE_TYPE_QUALIFIER_FILE_VERSION gcmCC(0, 0, 1, 3)
+
+/* bump up version to 1.4 for variable type qualifier support on 4/2/2012 */
+#define gcdSL_SHADER_BINARY_BEFORE_PRECISION_QUALIFIER_FILE_VERSION gcmCC(0, 0, 1, 4)
+
+/* bump up version to 1.5 for precision qualifier support on 8/23/2012 */
+#define gcdSL_SHADER_BINARY_BEFORE_HALTI_FILE_VERSION gcmCC(0, 0, 1, 5)
+
+/* bump up version to 1.6 for halti feature support on 9/10/2012 */
+#define gcdSL_SHADER_BINARY_BEFORE_IR_CHANGE_FILE_VERSION gcmCC(0, 0, 1, 6)
+
+/* bump up version to 1.7 for openCL image sampler with TEXLD support on 9/18/2013 */
+#define gcdSL_SHADER_BINARY_BEFORE_OPENCL_IMAGE_SAMPLER_BY_TEXLD_FILE_VERSION gcmCC(0, 0, 1, 7)
+
+/* bump up version to 1.8 for IR change support on 9/19/2013 */
+#define gcdSL_SHADER_BINARY_VERSION_9_19_2013 gcmCC(0, 0, 1, 8)
+
+/* bump up version to 1.9 for ES31 features support on 4/22/2014 */
+#define gcdSL_SHADER_BINARY_BEFORE_ES31_VERSION gcmCC(0, 0, 1, 9)
+
+/* bump up version to 1.10 for OPENCL1.2 features support on 8/22/2014 */
+#define gcdSL_SHADER_BINARY_BEFORE_CL12_VERSION gcmCC(0, 0, 1, 10)
+
+/* bump up version to 1.11 for ES31 uniform location support on 8/28/2014 */
+#define gcdSL_SHADER_BINARY_BEFORE_ES31_UNIFORM_LOCATION_VERSION gcmCC(0, 0, 1, 11)
+
+/* bump up version to 1.12 for invariant support on 10/20/2014 */
+#define gcdSL_SHADER_BINARY_BEFORE_ADD_INVARIANT_VERSION gcmCC(0, 0, 1, 12)
+
+/* bump up version to 1.13 for OCL uniform block support on 11/15/2014 */
+#define gcdSL_SHADER_BINARY_BEFORE_OCL_UNIFORM_BLOCK_VERSION gcmCC(0, 0, 1, 13)
+
+/* bump up version to 1.14 for ES31 uniform base binding index support on 04/07/2015 */
+#define gcdSL_SHADER_BINARY_BEFORE_UNIFORM_BASE_BINDING_VERSION gcmCC(0, 0, 1, 14)
+
+/* bump up version to 1.15 for enlarge type size from 8 bit to 16 bit on 06/25/2015 */
+#define gcdSL_SHADER_BINARY_BEFORE_16BIT_TYPE_VERSION gcmCC(0, 0, 1, 15)
+
+/* bump up version to 1.16 for ltc dummy uniform index on 09/23/2016 */
+#define gcdSL_SHADER_BINARY_BEFORE_DUMMY_UNIFORM_INDEX_VERSION gcmCC(0, 0, 1, 16)
+
+/* bump up version to 1.17 for type name var index on 03/16/2017 */
+#define gcdSL_SHADER_BINARY_BEFORE_SAVEING_TYPE_NAME_VAR_INDEX gcmCC(0, 0, 1, 17)
+
+/* bump up version to 1.18 for uniform physical addr on 04/13/2017 */
+#define gcdSL_SHADER_BINARY_BEFORE_SAVEING_UNIFORM_PHYSICAL_ADDR gcmCC(0, 0, 1, 18)
+
+/* bump up version to 1.19 for uniform physical addr on 09/06/2017 */
+#define gcdSL_SHADER_BINARY_BEFORE_SAVEING_UNIFORM_RES_OP_FLAG gcmCC(0, 0, 1, 19)
+
+/* bump up version to 1.20 for new header with chipModel and chpRevision on 11/30/2017 */
+#define gcdSL_SHADER_BINARY_BEFORE_SAVEING_CHIPMODEL gcmCC(0, 0, 1, 20)
+
+/* bump up version to 1.22 for new changes merged from dev_129469 branch on 11/21/2017 */
+#define gcdSL_SHADER_BINARY_BEFORE_MERGED_FROM_DEV_129469_FLAG gcmCC(0, 0, 1, 22)
+
+/* bump up version to 1.23 for remove VG from shader flags on 03/01/2018 */
+#define gcdSL_SHADER_BINARY_BEFORE_MOVE_VG_FROM_SHADER_FLAG gcmCC(0, 0, 1, 23)
+/* bump up version to 1.24 for adding transform feedback info on 08/20/2018 */
+
+/* bump up version to 1.26 for adding output's shader mode on 09/28/2018 */
+/* bump up version to 1.27 for modify _viv_atan2_float() to comform to CL spec on 11/20/2018 */
+/* bump up version to 1.28 for using HALTI5 trig functions for all cases (not just conformance) on 12/3/2018 */
+/* bump up version to 1.29 for new header with chipModel and chpRevision on 03/19/2019 */
+/* bump up version to 1.30 for saving source string on 03/26/2019 */
+/* bump up version to 1.31 for saving some flags in hints on 04/17/2019 */
+/* bump up version to 1.32 for saving some flags in hints on 04/25/2019 */
+/* bump up version to 1.33 for saving the shader source for OCL on 07/15/2019 */
+#define gcdSL_SHADER_BINARY_BEFORE_SAVING_SHADER_SOURCE_FOR_OCL gcmCC(0, 0, 1, 33)
+
+/* bump up version to 1.34 for workGroupSizeFactor into the binary on 07/18/2019 */
+/* bump up version to 1.35 for adding isBuiltinArray and builtinArrayIdx in TFBVarying on 07/19/2019 */
+/* bump up version to 1.36 for adding bEndOfInterleavedBuffer in TFBVarying on 07/22/2019 */
+/* bump up version to 1.37 for adding intrisinc functions for gSampler2DRect on 08/06/2019 */
+/* bump up version to 1.38 for saving the full graphics shaders into the binary on 08/08/2019 */
+/* bump up version to 1.39 for saving ubo array index into the binary on 08/09/2019 */
+
+/* current version */
+#define gcdSL_SHADER_BINARY_FILE_VERSION gcmCC(SHADER_64BITMODE, 0, 1, 39)
+
+#define gcdSL_PROGRAM_BINARY_FILE_VERSION gcmCC(SHADER_64BITMODE, 0, 1, 39)
+
+typedef union _gcsValue
+{
+    /* vector 16 value */
+    gctFLOAT         f32_v16[16];
+    gctINT32         i32_v16[16];
+    gctUINT32        u32_v16[16];
+
+    /* vector 4 value */
+    gctFLOAT         f32_v4[4];
+    gctINT32         i32_v4[4];
+    gctUINT32        u32_v4[4];
+
+    /* packed vector 16 value */
+    gctINT8          i8_v16[16];
+    gctUINT8         u8_v16[16];
+    gctINT16         i16_v16[16];
+    gctUINT16        u16_v16[16];
+
+    /* scalar value */
+    gctFLOAT         f32;
+    gctINT32         i32;
+    gctUINT32        u32;
+} gcsValue;
+
+/******************************************************************************\
+|******************************* SHADER LANGUAGE ******************************|
+\******************************************************************************/
+
+/* Shader types. */
+typedef enum _gcSHADER_KIND {
+    gcSHADER_TYPE_UNKNOWN = 0,
+    gcSHADER_TYPE_VERTEX,
+    gcSHADER_TYPE_FRAGMENT,
+    gcSHADER_TYPE_COMPUTE,
+    gcSHADER_TYPE_CL,
+    gcSHADER_TYPE_PRECOMPILED,
+    gcSHADER_TYPE_LIBRARY,
+    gcSHADER_TYPE_VERTEX_DEFAULT_UBO,
+    gcSHADER_TYPE_FRAGMENT_DEFAULT_UBO,
+    gcSHADER_TYPE_TCS,
+    gcSHADER_TYPE_TES,
+    gcSHADER_TYPE_GEOMETRY,
+    gcSHADER_KIND_COUNT
+} gcSHADER_KIND;
+
+typedef enum gceFRAGOUT_USAGE
+{
+    gcvFRAGOUT_USAGE_USER_DEFINED     = 0,
+    gcvFRAGOUT_USAGE_FRAGCOLOR        = 1,
+    gcvFRAGOUT_USAGE_FRAGDATA         = 2,
+}
+gceFRAGOUT_USAGE;
+
+#define gcSL_GetShaderKindString(Kind) (((Kind) == gcSHADER_TYPE_VERTEX) ? "VS" :        \
+                                        ((Kind) == gcSHADER_TYPE_FRAGMENT) ? "FS" :      \
+                                        ((Kind) == gcSHADER_TYPE_TCS) ? "TCS" :          \
+                                        ((Kind) == gcSHADER_TYPE_TES) ? "TES" :          \
+                                        ((Kind) == gcSHADER_TYPE_GEOMETRY) ? "GEO" :     \
+                                        ((Kind) == gcSHADER_TYPE_CL) ? "CL" :            \
+                                        ((Kind) == gcSHADER_TYPE_LIBRARY) ? "LIBRARY" :  \
+                                        ((Kind) == gcSHADER_TYPE_PRECOMPILED) ? "PRECOMPILED" :  \
+                                        ((Kind) == gcSHADER_TYPE_COMPUTE) ? "CS" : "??")
+
+#define _SHADER_GL_LANGUAGE_TYPE  gcmCC('E', 'S', '\0', '\0')
+#define _SHADER_DX_LANGUAGE_TYPE  gcmCC('D', 'X', '\0', '\0')
+#define _cldLanguageType          gcmCC('C', 'L', '\0', '\0')
+#define _SHADER_VG_TYPE           gcmCC('V', 'G', '\0', '\0')
+#define _SHADER_OGL_LANGUAGE_TYPE gcmCC('G', 'L', '\0', '\0')
+
+#define _SHADER_GL_VERSION_SIG    1
+
+#define _SHADER_ES11_VERSION      gcmCC('\0', '\0', '\1', '\1')
+#define _SHADER_HALTI_VERSION     gcmCC('\0', '\0', '\0', '\3')
+#define _SHADER_ES31_VERSION      gcmCC('\0', '\0', '\1', '\3')
+#define _SHADER_ES32_VERSION      gcmCC('\0', '\0', '\2', '\3')
+#define _SHADER_ES40_VERSION      gcmCC('\0', '\0', '\0', '\4')
+#define _SHADER_DX_VERSION_30     gcmCC('\3', '\0', '\0', '\0')
+#define _cldCL1Dot1               gcmCC('\0', '\0', '\0', '\1')
+#define _cldCL1Dot2               gcmCC('\0', '\0', '\2', '\1')
+#define _SHADER_GL11_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\1', '\1')
+#define _SHADER_GL20_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\0', '\2')
+#define _SHADER_GL21_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\1', '\2')
+#define _SHADER_GL30_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\0', '\3')
+#define _SHADER_GL31_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\1', '\3')
+#define _SHADER_GL32_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\2', '\3')
+#define _SHADER_GL33_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\3', '\3')
+#define _SHADER_GL40_VERSION      gcmCC('\0', _SHADER_GL_VERSION_SIG, '\0', '\4')
+
+#define gcShader_IsCL(S)           (GetShaderType(S) == gcSHADER_TYPE_CL && (((S)->compilerVersion[0] & 0xFFFF) == _cldLanguageType))
+#define gcShader_IsGlCompute(S)    (GetShaderType(S) == gcSHADER_TYPE_COMPUTE && (((S)->compilerVersion[0] & 0xFFFF) != _cldLanguageType))
+
+/* Client version. */
+typedef enum _gcSL_OPCODE
+{
+    gcSL_NOP, /* 0x00 */
+    gcSL_MOV, /* 0x01 */
+    gcSL_SAT, /* 0x02 */
+    gcSL_DP3, /* 0x03 */
+    gcSL_DP4, /* 0x04 */
+    gcSL_ABS, /* 0x05 */
+    gcSL_JMP, /* 0x06 */
+    gcSL_ADD, /* 0x07 */
+    gcSL_MUL, /* 0x08 */
+    gcSL_RCP, /* 0x09 */
+    gcSL_SUB, /* 0x0A */
+    gcSL_KILL, /* 0x0B */
+    gcSL_TEXLD, /* 0x0C */
+    gcSL_CALL, /* 0x0D */
+    gcSL_RET, /* 0x0E */
+    gcSL_NORM, /* 0x0F */
+    gcSL_MAX, /* 0x10 */
+    gcSL_MIN, /* 0x11 */
+    gcSL_POW, /* 0x12 */
+    gcSL_RSQ, /* 0x13 */
+    gcSL_LOG, /* 0x14 */
+    gcSL_FRAC, /* 0x15 */
+    gcSL_FLOOR, /* 0x16 */
+    gcSL_CEIL, /* 0x17 */
+    gcSL_CROSS, /* 0x18 */
+    gcSL_TEXLDPROJ, /* 0x19 */
+    gcSL_TEXBIAS, /* 0x1A */
+    gcSL_TEXGRAD, /* 0x1B */
+    gcSL_TEXLOD, /* 0x1C */
+    gcSL_SIN, /* 0x1D */
+    gcSL_COS, /* 0x1E */
+    gcSL_TAN, /* 0x1F */
+    gcSL_EXP, /* 0x20 */
+    gcSL_SIGN, /* 0x21 */
+    gcSL_STEP, /* 0x22 */
+    gcSL_SQRT, /* 0x23 */
+    gcSL_ACOS, /* 0x24 */
+    gcSL_ASIN, /* 0x25 */
+    gcSL_ATAN, /* 0x26 */
+    gcSL_SET, /* 0x27 */
+    gcSL_DSX, /* 0x28 */
+    gcSL_DSY, /* 0x29 */
+    gcSL_FWIDTH, /* 0x2A */
+    gcSL_DIV, /* 0x2B */
+    gcSL_MOD, /* 0x2C */
+    gcSL_AND_BITWISE, /* 0x2D */
+    gcSL_OR_BITWISE, /* 0x2E */
+    gcSL_XOR_BITWISE, /* 0x2F */
+    gcSL_NOT_BITWISE, /* 0x30 */
+    gcSL_LSHIFT, /* 0x31 */
+    gcSL_RSHIFT, /* 0x32 */
+    gcSL_ROTATE, /* 0x33 */
+    gcSL_BITSEL, /* 0x34 */
+    gcSL_LEADZERO, /* 0x35 */
+    gcSL_LOAD, /* 0x36 */
+    gcSL_STORE, /* 0x37 */
+    gcSL_BARRIER, /* 0x38 */
+    gcSL_STORE1, /* 0x39 */
+    gcSL_ATOMADD, /* 0x3A */
+    gcSL_ATOMSUB, /* 0x3B */
+    gcSL_ATOMXCHG, /* 0x3C */
+    gcSL_ATOMCMPXCHG, /* 0x3D */
+    gcSL_ATOMMIN, /* 0x3E */
+    gcSL_ATOMMAX, /* 0x3F */
+    gcSL_ATOMOR, /* 0x40 */
+    gcSL_ATOMAND, /* 0x41 */
+    gcSL_ATOMXOR, /* 0x42 */
+    gcSL_TEXLDPCF, /* 0x43 */
+    gcSL_TEXLDPCFPROJ, /* 0x44 */
+    gcSL_TEXLODQ, /* 0x45  ES31 */
+    gcSL_FLUSH, /* 0x46  ES31 */
+    gcSL_JMP_ANY, /* 0x47  ES31 */
+    gcSL_BITRANGE, /* 0x48  ES31 */
+    gcSL_BITRANGE1, /* 0x49  ES31 */
+    gcSL_BITEXTRACT, /* 0x4A  ES31 */
+    gcSL_BITINSERT, /* 0x4B  ES31 */
+    gcSL_FINDLSB, /* 0x4C  ES31 */
+    gcSL_FINDMSB, /* 0x4D  ES31 */
+    gcSL_IMAGE_OFFSET, /* 0x4E  ES31 */
+    gcSL_IMAGE_ADDR, /* 0x4F  ES31 */
+    gcSL_SINPI, /* 0x50 */
+    gcSL_COSPI, /* 0x51 */
+    gcSL_TANPI, /* 0x52 */
+    gcSL_ADDLO, /* 0x53 */  /* Float only. */
+    gcSL_MULLO, /* 0x54 */  /* Float only. */
+    gcSL_CONV, /* 0x55 */
+    gcSL_GETEXP, /* 0x56 */
+    gcSL_GETMANT, /* 0x57 */
+    gcSL_MULHI, /* 0x58 */  /* Integer only. */
+    gcSL_CMP, /* 0x59 */
+    gcSL_I2F, /* 0x5A */
+    gcSL_F2I, /* 0x5B */
+    gcSL_ADDSAT, /* 0x5C */  /* Integer only. */
+    gcSL_SUBSAT, /* 0x5D */  /* Integer only. */
+    gcSL_MULSAT, /* 0x5E */  /* Integer only. */
+    gcSL_DP2, /* 0x5F */
+    gcSL_UNPACK, /* 0x60 */
+    gcSL_IMAGE_WR, /* 0x61 */
+    gcSL_SAMPLER_ADD, /* 0x62 */
+    gcSL_MOVA, /* 0x63, HW MOVAR/MOVF/MOVI, VIRCG only */
+    gcSL_IMAGE_RD, /* 0x64 */
+    gcSL_IMAGE_SAMPLER, /* 0x65 */
+    gcSL_NORM_MUL, /* 0x66  VIRCG only */
+    gcSL_NORM_DP2, /* 0x67  VIRCG only */
+    gcSL_NORM_DP3, /* 0x68  VIRCG only */
+    gcSL_NORM_DP4, /* 0x69  VIRCG only */
+    gcSL_PRE_DIV, /* 0x6A  VIRCG only */
+    gcSL_PRE_LOG2, /* 0x6B  VIRCG only */
+    gcSL_TEXGATHER, /* 0x6C  ES31 */
+    gcSL_TEXFETCH_MS, /* 0x6D  ES31 */
+    gcSL_POPCOUNT, /* 0x6E  ES31(OCL1.2)*/
+    gcSL_BIT_REVERSAL, /* 0x6F  ES31 */
+    gcSL_BYTE_REVERSAL, /* 0x70  ES31 */
+    gcSL_TEXPCF, /* 0x71  ES31 */
+    gcSL_UCARRY, /* 0x72  ES31 UCARRY is a condition op, while gcSL
+                                                 has not enough bits to represent more */
+
+    gcSL_TEXU, /* 0x73  paired with gcSL_TEXLD to implement HW texld_u_plain */
+    gcSL_TEXU_LOD, /* 0x74  paired with gcSL_TEXLD to implement HW texld_u_lod */
+    gcSL_MEM_BARRIER, /* 0x75  Memory Barrier. */
+    gcSL_SAMPLER_ASSIGN, /* 0x76  Sampler assignment as a parameter, only exist on FE. */
+    gcSL_GET_SAMPLER_IDX, /* 0x77  Get Image/Sampler index */
+
+    gcSL_IMAGE_RD_3D, /* 0x78 */
+    gcSL_IMAGE_WR_3D, /* 0x79 */
+    gcSL_CLAMP0MAX, /* 0x7A clamp0max dest, value, max */
+    gcSL_FMA_MUL, /* 0x7B FMA first part: MUL */
+    gcSL_FMA_ADD, /* 0x7C FMA second part: ADD */
+    gcSL_ATTR_ST, /* 0x7D ATTR_ST attribute(0+temp(1).x), InvocationIndex, val */
+    gcSL_ATTR_LD, /* 0x7E ATTR_LD dest, attribute(0+temp(1).x), InvocationIndex */
+    gcSL_EMIT_VERTEX, /* 0x7F For function "EmitVertex" */
+    gcSL_END_PRIMITIVE, /* 0x80 For function "EndPrimitive" */
+    gcSL_ARCTRIG0, /* 0x81 For triangle functions */
+    gcSL_ARCTRIG1, /* 0x82 For triangle functions */
+    gcSL_MUL_Z, /* 0x83 special mul, resulting in 0 from inf * 0 */
+    gcSL_NEG, /* 0x84 neg(a) is similar to (0 - (a)) */
+    gcSL_LONGLO, /* 0x85 get the lower 4 bytes of a long/ulong integer */
+    gcSL_LONGHI, /* 0x86 get the upper 4 bytes of a long/ulong integer */
+    gcSL_MOV_LONG, /* 0x87 mov two 4 byte integers to the lower/upper 4 bytes of a long/ulong integer */
+    gcSL_MADSAT, /* 0x88 mad with saturation for integer only */
+    gcSL_COPY, /* 0x89 copy register contents */
+    gcSL_LOAD_L, /* 0x8A load data from local memory */
+    gcSL_STORE_L, /* 0x8B store data to local memory */
+    gcSL_IMAGE_ADDR_3D, /* 0x8C */
+    gcSL_GET_SAMPLER_LMM, /* 0x8D Get sampler's lodminmax */
+    gcSL_GET_SAMPLER_LBS, /* 0x8E Get sampler's levelbasesize */
+    gcSL_TEXLD_U, /* 0x8F For TEXLD_U, use the format of coord to select FLOAT/INT/UNSIGINED. */
+    gcSL_PARAM_CHAIN, /* 0x90 No specific semantic, only used to chain two sources to one dest. */
+    gcSL_INTRINSIC, /* 0x91 Instrinsic dest, IntrinsicId, Param */
+    gcSL_INTRINSIC_ST, /* 0x92 Instrinsic dest, IntrinsicId, Param; Param is stored implicitly */
+    gcSL_CMAD, /* 0x93 Complex number mad. */
+    gcSL_CONJ, /* 0x94 Conjugate modifier. */
+    gcSL_CMUL, /* 0x95 Complex number mul. */
+    gcSL_CMADCJ, /* 0x96 Complex number conjugate mad. */
+    gcSL_CMULCJ, /* 0x97 Complex number conjugate mul. */
+    gcSL_CADDCJ, /* 0x98 Complex number conjugate add. */
+    gcSL_CSUBCJ, /* 0x99 Complex number conjugate sub. */
+    gcSL_CADD, /* 0x9A Complex number add. */
+    gcSL_GET_IMAGE_TYPE, /* 0x9B get the image type: 0-1d, 1-1dbuffer, 2-1darray, 3-2d, 4-2darray, 5-3d */
+    gcSL_CLAMPCOORD, /* clamp image 2d cooridate to its width and height */
+    gcSL_MAXOPCODE
+}
+gcSL_OPCODE;
+
+#define gcSL_isOpcodeTexld(Opcode)         ((Opcode) == gcSL_TEXLD         ||    \
+                                            (Opcode) == gcSL_TEXLD_U       ||    \
+                                            (Opcode) == gcSL_TEXLDPROJ     ||    \
+                                            (Opcode) == gcSL_TEXLDPCF      ||    \
+                                            (Opcode) == gcSL_TEXLODQ       ||    \
+                                            (Opcode) == gcSL_TEXLDPCFPROJ)
+
+#define gcSL_isOpcodeTexldModifier(Opcode) ((Opcode) == gcSL_TEXBIAS ||    \
+                                            (Opcode) == gcSL_TEXLOD ||     \
+                                            (Opcode) == gcSL_TEXGRAD ||    \
+                                            (Opcode) == gcSL_TEXGATHER ||  \
+                                            (Opcode) == gcSL_TEXFETCH_MS || \
+                                            (Opcode) == gcSL_TEXU || \
+                                            (Opcode) == gcSL_TEXU_LOD)
+
+#define gcSL_isOpcodeAtom(Opcode)          ((Opcode) == gcSL_ATOMADD       ||   \
+                                            (Opcode) == gcSL_ATOMSUB       ||   \
+                                            (Opcode) == gcSL_ATOMXCHG      ||   \
+                                            (Opcode) == gcSL_ATOMCMPXCHG   ||   \
+                                            (Opcode) == gcSL_ATOMMIN       ||   \
+                                            (Opcode) == gcSL_ATOMMAX       ||   \
+                                            (Opcode) == gcSL_ATOMOR        ||   \
+                                            (Opcode) == gcSL_ATOMAND       ||   \
+                                            (Opcode) == gcSL_ATOMXOR)
+
+/* according to decode[] */
+#define gcSL_isOpcodeHaveNoTarget(Opcode)       ((Opcode) == gcSL_NOP                 ||  \
+                                                 (Opcode) == gcSL_JMP                 ||  \
+                                                 (Opcode) == gcSL_JMP_ANY             ||  \
+                                                 (Opcode) == gcSL_KILL                ||  \
+                                                 (Opcode) == gcSL_CALL                ||  \
+                                                 (Opcode) == gcSL_RET                 ||  \
+                                                 (Opcode) == gcSL_TEXBIAS             ||  \
+                                                 (Opcode) == gcSL_TEXGRAD             ||  \
+                                                 (Opcode) == gcSL_TEXLOD              ||  \
+                                                 (Opcode) == gcSL_BARRIER             ||  \
+                                                 (Opcode) == gcSL_FLUSH               ||  \
+                                                 (Opcode) == gcSL_IMAGE_OFFSET        ||  \
+                                                 (Opcode) == gcSL_IMAGE_SAMPLER       ||  \
+                                                 (Opcode) == gcSL_TEXGATHER           ||  \
+                                                 (Opcode) == gcSL_TEXFETCH_MS         ||  \
+                                                 (Opcode) == gcSL_TEXPCF              ||  \
+                                                 (Opcode) == gcSL_TEXU                ||  \
+                                                 (Opcode) == gcSL_TEXU_LOD            ||  \
+                                                 (Opcode) == gcSL_MEM_BARRIER         ||  \
+                                                 (Opcode) == gcSL_EMIT_VERTEX         ||  \
+                                                 (Opcode) == gcSL_END_PRIMITIVE)
+
+#define gcSL_isOpcodeUseTargetAsSource(Opcode)  ((Opcode) == gcSL_STORE               ||  \
+                                                 (Opcode) == gcSL_IMAGE_WR            ||  \
+                                                 (Opcode) == gcSL_IMAGE_WR_3D         ||  \
+                                                 (Opcode) == gcSL_ATTR_ST)
+
+#define gcSL_isOpcodeTargetInvalid(Opcode)      ((Opcode) == gcSL_STORE               ||  \
+                                                 (Opcode) == gcSL_STORE1              ||  \
+                                                 (Opcode) == gcSL_STORE_L             ||  \
+                                                 (Opcode) == gcSL_IMAGE_WR            ||  \
+                                                 (Opcode) == gcSL_IMAGE_WR_3D         ||  \
+                                                 (Opcode) == gcSL_ATTR_ST)
+
+#define gcSL_isOpcodeImageRead(Opcode)          ((Opcode) == gcSL_IMAGE_RD            ||  \
+                                                 (Opcode) == gcSL_IMAGE_RD_3D)
+
+#define gcSL_isOpcodeImageWrite(Opcode)         ((Opcode) == gcSL_IMAGE_WR            ||  \
+                                                 (Opcode) == gcSL_IMAGE_WR_3D)
+
+#define gcSL_isOpcodeImageAddr(Opcode)          ((Opcode) == gcSL_IMAGE_ADDR          ||  \
+                                                 (Opcode) == gcSL_IMAGE_ADDR_3D)
+
+#define gcSL_isOpcodeImageRelated(Opcode)       (gcSL_isOpcodeImageRead(Opcode)       ||  \
+                                                 gcSL_isOpcodeImageWrite(Opcode)      ||  \
+                                                 gcSL_isOpcodeImageAddr(Opcode))
+
+#define gcSL_isComplexRelated(Opcode)           ((Opcode) == gcSL_CMAD                ||  \
+                                                 (Opcode) == gcSL_CMUL                ||  \
+                                                 (Opcode) == gcSL_CONJ                ||  \
+                                                 (Opcode) == gcSL_CMADCJ              ||  \
+                                                 (Opcode) == gcSL_CMULCJ              ||  \
+                                                 (Opcode) == gcSL_CADDCJ              ||  \
+                                                 (Opcode) == gcSL_CSUBCJ                  \
+                                                 )
+
+typedef enum _gcSL_OPCODE_ATTR_RESULT_PRECISION
+{
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_INVALID = 0,
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_HIA = 1, /* highest precision in both operands */
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_AF = 2, /* as the precision of the first operand */
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_AS = 3, /* as the precision of the second operand */
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_HP = 4, /* highp */
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_MP = 5, /* mediump */
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_LP = 6, /* lowp */
+    _gcSL_OPCODE_ATTR_RESULT_PRECISION_IGNORE = 7, /* the precision doesn't matter */
+} gcSL_OPCODE_ATTR_RESULT_PRECISION;
+
+typedef struct _gcSL_OPCODE_ATTR
+{
+    gcSL_OPCODE_ATTR_RESULT_PRECISION resultPrecision;
+}
+gcSL_OPCODE_ATTR;
+
+extern const gcSL_OPCODE_ATTR gcvOpcodeAttr[];
+
+typedef enum _gcSL_BARRIER_TYPE
+{
+    gcSL_BARRIER_NORMAL = 0,
+    gcSL_BARRIER_LOCAL,
+    gcSL_BARRIER_GLOBAL,
+    gcSL_BARRIER_MEM,
+    gcSL_BARRIER_MEM_ATOMIC_COUNTER,
+    gcSL_BARRIER_MEM_BUFFER,
+    gcSL_BARRIER_MEM_IMAGE,
+    gcSL_BARRIER_MEM_SHARED,
+    gcSL_BARRIER_MEM_GROUP
+}
+gcSL_BARRIER_TYPE;
+
+typedef enum _gcSL_FORMAT
+{
+    gcSL_FLOAT = 0, /* 0 */
+    gcSL_INTEGER = 1, /* 1 */
+    gcSL_INT32 = 1, /* 1 */
+    gcSL_BOOLEAN = 2, /* 2 */
+    gcSL_UINT32 = 3, /* 3 */
+    gcSL_INT8, /* 4 */
+    gcSL_UINT8, /* 5 */
+    gcSL_INT16, /* 6 */
+    gcSL_UINT16, /* 7 */
+    gcSL_INT64, /* 8 */
+    gcSL_UINT64, /* 9 */
+    gcSL_SNORM8, /* 10 */
+    gcSL_UNORM8, /* 11 */
+    gcSL_FLOAT16, /* 12 */
+    gcSL_FLOAT64, /* 13 */    /* Reserved for future enhancement. */
+    gcSL_SNORM16, /* 14 */
+    gcSL_UNORM16, /* 15 */
+    gcSL_INVALID, /* 16 */
+/* the following is extended for OCL 1.2 for type name querying
+   the lower 4 bits are defined as above.
+   An aggregate format can be formed from or'ing together a value from above
+   and another value from below
+*/
+    gcSL_VOID      = 0x011, /* to support OCL 1.2 for querying */
+    gcSL_SAMPLER_T = 0x012, /* OCL sampler_t */
+    gcSL_SIZE_T    = 0x013, /* OCL size_t */
+    gcSL_EVENT_T   = 0x014, /* OCL event */
+    gcSL_PTRDIFF_T = 0x015, /* OCL prtdiff_t */
+    gcSL_INTPTR_T  = 0x016, /* OCL intptr_t */
+    gcSL_UINTPTR_T = 0x017, /* OCL uintptr_t */
+    gcSL_STRUCT    = 0x100, /* OCL struct */
+    gcSL_UNION     = 0x200, /* OCL union */
+    gcSL_ENUM      = 0x300, /* OCL enum */
+    gcSL_TYPEDEF   = 0x400, /* OCL typedef */
+}
+gcSL_FORMAT;
+
+#define GetFormatBasicType(f)       ((f) & 0xFF)
+#define GetFormatSpecialType(f)     ((f) & ~0xFF)
+#define isFormatSpecialType(f)      (GetFormatSpecialType(f) != 0)
+#define SetFormatSpecialType(f, t)  do {                                                        \
+                                        gcmASSERT(isFormatSpecialType(t));                      \
+                                        (f) = GetFormatBasicType(f) | GetFormatSpecialType(t);  \
+                                    } while (0)
+
+#define isFormat64bit(f)   ((f) == gcSL_INT64 || (f) == gcSL_UINT64)
+
+/* Destination write enable bits. */
+typedef enum _gcSL_ENABLE
+{
+    gcSL_ENABLE_NONE                     = 0x0, /* none is enabled, error/uninitialized state */
+    gcSL_ENABLE_X                        = 0x1,
+    gcSL_ENABLE_Y                        = 0x2,
+    gcSL_ENABLE_Z                        = 0x4,
+    gcSL_ENABLE_W                        = 0x8,
+    /* Combinations. */
+    gcSL_ENABLE_XY                       = gcSL_ENABLE_X | gcSL_ENABLE_Y,
+    gcSL_ENABLE_XYZ                      = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z,
+    gcSL_ENABLE_XYZW                     = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
+    gcSL_ENABLE_XYW                      = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_W,
+    gcSL_ENABLE_XZ                       = gcSL_ENABLE_X | gcSL_ENABLE_Z,
+    gcSL_ENABLE_XZW                      = gcSL_ENABLE_X | gcSL_ENABLE_Z | gcSL_ENABLE_W,
+    gcSL_ENABLE_XW                       = gcSL_ENABLE_X | gcSL_ENABLE_W,
+    gcSL_ENABLE_YZ                       = gcSL_ENABLE_Y | gcSL_ENABLE_Z,
+    gcSL_ENABLE_YZW                      = gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
+    gcSL_ENABLE_YW                       = gcSL_ENABLE_Y | gcSL_ENABLE_W,
+    gcSL_ENABLE_ZW                       = gcSL_ENABLE_Z | gcSL_ENABLE_W,
+}
+gcSL_ENABLE;
+
+#define gcmEnableChannelCount(enable)          \
+    (((enable) & 0x1) + (((enable) & 0x2) >> 1) + (((enable) & 0x4) >> 2) + (((enable) & 0x8) >> 3))
+
+/* Possible indices. */
+typedef enum _gcSL_INDEXED
+{
+    gcSL_NOT_INDEXED, /* 0 */
+    gcSL_INDEXED_X, /* 1 */
+    gcSL_INDEXED_Y, /* 2 */
+    gcSL_INDEXED_Z, /* 3 */
+    gcSL_INDEXED_W, /* 4 */
+}
+gcSL_INDEXED;
+
+/* Possible indices. */
+typedef enum _gcSL_INDEXED_LEVEL
+{
+    gcSL_NONE_INDEXED, /* 0 */
+    gcSL_LEAF_INDEXED, /* 1 */
+    gcSL_NODE_INDEXED, /* 2 */
+    gcSL_LEAF_AND_NODE_INDEXED             /* 3 */
+}
+gcSL_INDEXED_LEVEL;
+
+/* Opcode conditions. */
+typedef enum _gcSL_CONDITION
+{
+    gcSL_ALWAYS, /* 0x0 */
+    gcSL_NOT_EQUAL, /* 0x1 */
+    gcSL_LESS_OR_EQUAL, /* 0x2 */
+    gcSL_LESS, /* 0x3 */
+    gcSL_EQUAL, /* 0x4 */
+    gcSL_GREATER, /* 0x5 */
+    gcSL_GREATER_OR_EQUAL, /* 0x6 */
+    gcSL_AND, /* 0x7 */
+    gcSL_OR, /* 0x8 */
+    gcSL_XOR, /* 0x9 */
+    gcSL_NOT_ZERO, /* 0xA */
+    gcSL_ZERO, /* 0xB */
+    gcSL_GREATER_OR_EQUAL_ZERO, /* 0xC */
+    gcSL_GREATER_ZERO, /* 0xD */
+    gcSL_LESS_OREQUAL_ZERO, /* 0xE */
+    gcSL_LESS_ZERO, /* 0xF */
+    gcSL_ALLMSB, /* 0x10*/
+    gcSL_ANYMSB, /* 0x11*/
+    gcSL_SELMSB, /* 0x12*/
+}
+gcSL_CONDITION;
+
+/* Possible source operand types. */
+typedef enum _gcSL_TYPE
+{
+    gcSL_NONE, /* 0x0 */
+    gcSL_TEMP, /* 0x1 */
+    gcSL_ATTRIBUTE, /* 0x2 */
+    gcSL_UNIFORM, /* 0x3 */
+    gcSL_SAMPLER, /* 0x4 */
+    gcSL_CONSTANT, /* 0x5 */
+    gcSL_OUTPUT, /* 0x6 */
+}
+gcSL_TYPE;
+
+/* Swizzle generator macro. */
+#define gcmSWIZZLE(Component1, Component2, Component3, Component4) \
+(\
+    (gcSL_SWIZZLE_ ## Component1 << 0) | \
+    (gcSL_SWIZZLE_ ## Component2 << 2) | \
+    (gcSL_SWIZZLE_ ## Component3 << 4) | \
+    (gcSL_SWIZZLE_ ## Component4 << 6)   \
+)
+
+#define gcmExtractSwizzle(Swizzle, Index) \
+    ((gcSL_SWIZZLE) ((((Swizzle) >> (Index * 2)) & 0x3)))
+
+#define gcmComposeSwizzle(SwizzleX, SwizzleY, SwizzleZ, SwizzleW) \
+(\
+    ((SwizzleX) << 0) | \
+    ((SwizzleY) << 2) | \
+    ((SwizzleZ) << 4) | \
+    ((SwizzleW) << 6)   \
+)
+
+/* Possible swizzle values. */
+typedef enum _gcSL_SWIZZLE
+{
+    gcSL_SWIZZLE_X, /* 0x0 */
+    gcSL_SWIZZLE_Y, /* 0x1 */
+    gcSL_SWIZZLE_Z, /* 0x2 */
+    gcSL_SWIZZLE_W, /* 0x3 */
+    /* Combinations. */
+    gcSL_SWIZZLE_XXXX = gcmSWIZZLE(X, X, X, X),
+    gcSL_SWIZZLE_YYYY = gcmSWIZZLE(Y, Y, Y, Y),
+    gcSL_SWIZZLE_ZZZZ = gcmSWIZZLE(Z, Z, Z, Z),
+    gcSL_SWIZZLE_WWWW = gcmSWIZZLE(W, W, W, W),
+    gcSL_SWIZZLE_XYYY = gcmSWIZZLE(X, Y, Y, Y),
+    gcSL_SWIZZLE_XZZZ = gcmSWIZZLE(X, Z, Z, Z),
+    gcSL_SWIZZLE_XWWW = gcmSWIZZLE(X, W, W, W),
+    gcSL_SWIZZLE_YZZZ = gcmSWIZZLE(Y, Z, Z, Z),
+    gcSL_SWIZZLE_YWWW = gcmSWIZZLE(Y, W, W, W),
+    gcSL_SWIZZLE_ZWWW = gcmSWIZZLE(Z, W, W, W),
+    gcSL_SWIZZLE_XYZZ = gcmSWIZZLE(X, Y, Z, Z),
+    gcSL_SWIZZLE_XYWW = gcmSWIZZLE(X, Y, W, W),
+    gcSL_SWIZZLE_XZWW = gcmSWIZZLE(X, Z, W, W),
+    gcSL_SWIZZLE_YZWW = gcmSWIZZLE(Y, Z, W, W),
+    gcSL_SWIZZLE_XXYZ = gcmSWIZZLE(X, X, Y, Z),
+    gcSL_SWIZZLE_XYZW = gcmSWIZZLE(X, Y, Z, W),
+    gcSL_SWIZZLE_XYXY = gcmSWIZZLE(X, Y, X, Y),
+    gcSL_SWIZZLE_YYZZ = gcmSWIZZLE(Y, Y, Z, Z),
+    gcSL_SWIZZLE_YYWW = gcmSWIZZLE(Y, Y, W, W),
+    gcSL_SWIZZLE_ZZZW = gcmSWIZZLE(Z, Z, Z, W),
+    gcSL_SWIZZLE_XZZW = gcmSWIZZLE(X, Z, Z, W),
+    gcSL_SWIZZLE_YYZW = gcmSWIZZLE(Y, Y, Z, W),
+    gcSL_SWIZZLE_XXXY = gcmSWIZZLE(X, X, X, Y),
+    gcSL_SWIZZLE_XZXZ = gcmSWIZZLE(X, Z, X, Z),
+    gcSL_SWIZZLE_YWWY = gcmSWIZZLE(Y, W, W, Y),
+    gcSL_SWIZZLE_ZWZW = gcmSWIZZLE(Z, W, Z, W),
+
+    gcSL_SWIZZLE_INVALID = 0x7FFFFFFF
+}
+gcSL_SWIZZLE;
+
+typedef enum _gcSL_COMPONENT
+{
+    gcSL_COMPONENT_X, /* 0x0 */
+    gcSL_COMPONENT_Y, /* 0x1 */
+    gcSL_COMPONENT_Z, /* 0x2 */
+    gcSL_COMPONENT_W, /* 0x3 */
+    gcSL_COMPONENT_COUNT            /* 0x4 */
+} gcSL_COMPONENT;
+
+#define gcmIsComponentEnabled(Enable, Component) (((Enable) & (1 << (Component))) != 0)
+
+/* Rounding modes. */
+typedef enum _gcSL_ROUND
+{
+    gcSL_ROUND_DEFAULT, /* 0x0 */
+    gcSL_ROUND_RTZ, /* 0x1 */
+    gcSL_ROUND_RTNE, /* 0x2 */
+    gcSL_ROUND_RTP, /* 0x3 */
+    gcSL_ROUND_RTN                  /* 0x4 */
+} gcSL_ROUND;
+
+/* Saturation */
+typedef enum _gcSL_MODIFIER_SAT
+{
+    gcSL_NO_SATURATE, /* 0x0 */
+    gcSL_SATURATE            /* 0x1 */
+} gcSL_MODIFIER_SAT;
+
+/* Opcode flag modes. */
+typedef enum _gcSL_OPCODE_RES_TYPE
+{
+    gcSL_OPCODE_RES_TYPE_NONE           = 0x0,
+    gcSL_OPCODE_RES_TYPE_FETCH          = 0x1,
+    gcSL_OPCODE_RES_TYPE_FETCH_MS       = 0x2,
+} gcSL_OPCODE_RES_TYPE;
+
+/* Precision setting. */
+typedef enum _gcSL_PRECISION
+{
+    gcSL_PRECISION_DEFAULT, /* 0x0 */
+    gcSL_PRECISION_LOW, /* 0x1 */
+    gcSL_PRECISION_MEDIUM, /* 0x2 */
+    gcSL_PRECISION_HIGH, /* 0x3 */
+    gcSL_PRECISION_ANY, /* 0x4 */
+} gcSL_PRECISION;
+
+/* gcSHADER_TYPE enumeration. */
+typedef enum _gcSHADER_TYPE
+{
+    gcSHADER_FLOAT_X1   = 0, /* 0x00 */
+    gcSHADER_FLOAT_X2, /* 0x01 */
+    gcSHADER_FLOAT_X3, /* 0x02 */
+    gcSHADER_FLOAT_X4, /* 0x03 */
+    gcSHADER_FLOAT_2X2, /* 0x04 */
+    gcSHADER_FLOAT_3X3, /* 0x05 */
+    gcSHADER_FLOAT_4X4, /* 0x06 */
+    gcSHADER_BOOLEAN_X1, /* 0x07 */
+    gcSHADER_BOOLEAN_X2, /* 0x08 */
+    gcSHADER_BOOLEAN_X3, /* 0x09 */
+    gcSHADER_BOOLEAN_X4, /* 0x0A */
+    gcSHADER_INTEGER_X1, /* 0x0B */
+    gcSHADER_INTEGER_X2, /* 0x0C */
+    gcSHADER_INTEGER_X3, /* 0x0D */
+    gcSHADER_INTEGER_X4, /* 0x0E */
+    gcSHADER_SAMPLER_1D, /* 0x0F */
+    gcSHADER_SAMPLER_2D, /* 0x10 */
+    gcSHADER_SAMPLER_3D, /* 0x11 */
+    gcSHADER_SAMPLER_CUBIC, /* 0x12 */
+    gcSHADER_FIXED_X1, /* 0x13 */
+    gcSHADER_FIXED_X2, /* 0x14 */
+    gcSHADER_FIXED_X3, /* 0x15 */
+    gcSHADER_FIXED_X4, /* 0x16 */
+
+    /* For OCL. */
+    gcSHADER_IMAGE_1D_T, /* 0x17 */
+    gcSHADER_IMAGE_1D_BUFFER_T, /* 0x18 */
+    gcSHADER_IMAGE_1D_ARRAY_T, /* 0x19 */
+    gcSHADER_IMAGE_2D_T, /* 0x1A */
+    gcSHADER_IMAGE_2D_ARRAY_T, /* 0x1B */
+    gcSHADER_IMAGE_3D_T, /* 0x1C */
+    gcSHADER_VIV_GENERIC_IMAGE_T, /* 0x1D */
+    gcSHADER_SAMPLER_T, /* 0x1E */
+
+    gcSHADER_FLOAT_2X3, /* 0x1F */
+    gcSHADER_FLOAT_2X4, /* 0x20 */
+    gcSHADER_FLOAT_3X2, /* 0x21 */
+    gcSHADER_FLOAT_3X4, /* 0x22 */
+    gcSHADER_FLOAT_4X2, /* 0x23 */
+    gcSHADER_FLOAT_4X3, /* 0x24 */
+    gcSHADER_ISAMPLER_2D, /* 0x25 */
+    gcSHADER_ISAMPLER_3D, /* 0x26 */
+    gcSHADER_ISAMPLER_CUBIC, /* 0x27 */
+    gcSHADER_USAMPLER_2D, /* 0x28 */
+    gcSHADER_USAMPLER_3D, /* 0x29 */
+    gcSHADER_USAMPLER_CUBIC, /* 0x2A */
+    gcSHADER_SAMPLER_EXTERNAL_OES, /* 0x2B */
+
+    gcSHADER_UINT_X1, /* 0x2C */
+    gcSHADER_UINT_X2, /* 0x2D */
+    gcSHADER_UINT_X3, /* 0x2E */
+    gcSHADER_UINT_X4, /* 0x2F */
+
+    gcSHADER_SAMPLER_2D_SHADOW, /* 0x30 */
+    gcSHADER_SAMPLER_CUBE_SHADOW, /* 0x31 */
+
+    gcSHADER_SAMPLER_1D_ARRAY, /* 0x32 */
+    gcSHADER_SAMPLER_1D_ARRAY_SHADOW, /* 0x33 */
+    gcSHADER_SAMPLER_2D_ARRAY, /* 0x34 */
+    gcSHADER_ISAMPLER_2D_ARRAY, /* 0x35 */
+    gcSHADER_USAMPLER_2D_ARRAY, /* 0x36 */
+    gcSHADER_SAMPLER_2D_ARRAY_SHADOW, /* 0x37 */
+
+    gcSHADER_SAMPLER_2D_MS, /* 0x38 */
+    gcSHADER_ISAMPLER_2D_MS, /* 0x39 */
+    gcSHADER_USAMPLER_2D_MS, /* 0x3A */
+    gcSHADER_SAMPLER_2D_MS_ARRAY, /* 0x3B */
+    gcSHADER_ISAMPLER_2D_MS_ARRAY, /* 0x3C */
+    gcSHADER_USAMPLER_2D_MS_ARRAY, /* 0x3D */
+
+    gcSHADER_IMAGE_2D, /* 0x3E */
+    gcSHADER_IIMAGE_2D, /* 0x3F */
+    gcSHADER_UIMAGE_2D, /* 0x40 */
+    gcSHADER_IMAGE_3D, /* 0x41 */
+    gcSHADER_IIMAGE_3D, /* 0x42 */
+    gcSHADER_UIMAGE_3D, /* 0x43 */
+    gcSHADER_IMAGE_CUBE, /* 0x44 */
+    gcSHADER_IIMAGE_CUBE, /* 0x45 */
+    gcSHADER_UIMAGE_CUBE, /* 0x46 */
+    gcSHADER_IMAGE_2D_ARRAY, /* 0x47 */
+    gcSHADER_IIMAGE_2D_ARRAY, /* 0x48 */
+    gcSHADER_UIMAGE_2D_ARRAY, /* 0x49 */
+    gcSHADER_VIV_GENERIC_GL_IMAGE, /* 0x4A */
+
+    gcSHADER_ATOMIC_UINT, /* 0x4B */
+
+    /* GL_EXT_texture_cube_map_array */
+    gcSHADER_SAMPLER_CUBEMAP_ARRAY, /* 0x4C */
+    gcSHADER_SAMPLER_CUBEMAP_ARRAY_SHADOW, /* 0x4D */
+    gcSHADER_ISAMPLER_CUBEMAP_ARRAY, /* 0x4E */
+    gcSHADER_USAMPLER_CUBEMAP_ARRAY, /* 0x4F */
+    gcSHADER_IMAGE_CUBEMAP_ARRAY, /* 0x50 */
+    gcSHADER_IIMAGE_CUBEMAP_ARRAY, /* 0x51 */
+    gcSHADER_UIMAGE_CUBEMAP_ARRAY, /* 0x52 */
+
+    gcSHADER_INT64_X1, /* 0x53 */
+    gcSHADER_INT64_X2, /* 0x54 */
+    gcSHADER_INT64_X3, /* 0x55 */
+    gcSHADER_INT64_X4, /* 0x56 */
+    gcSHADER_UINT64_X1, /* 0x57 */
+    gcSHADER_UINT64_X2, /* 0x58 */
+    gcSHADER_UINT64_X3, /* 0x59 */
+    gcSHADER_UINT64_X4, /* 0x5A */
+
+    /* texture buffer extension type. */
+    gcSHADER_SAMPLER_BUFFER, /* 0x5B */
+    gcSHADER_ISAMPLER_BUFFER, /* 0x5C */
+    gcSHADER_USAMPLER_BUFFER, /* 0x5D */
+    gcSHADER_IMAGE_BUFFER, /* 0x5E */
+    gcSHADER_IIMAGE_BUFFER, /* 0x5F */
+    gcSHADER_UIMAGE_BUFFER, /* 0x60 */
+    gcSHADER_VIV_GENERIC_GL_SAMPLER, /* 0x61 */
+
+    /* float16 */
+    gcSHADER_FLOAT16_X1, /* 0x62 half2 */
+    gcSHADER_FLOAT16_X2, /* 0x63 half2 */
+    gcSHADER_FLOAT16_X3, /* 0x64 half3 */
+    gcSHADER_FLOAT16_X4, /* 0x65 half4 */
+    gcSHADER_FLOAT16_X8, /* 0x66 half8 */
+    gcSHADER_FLOAT16_X16, /* 0x67 half16 */
+    gcSHADER_FLOAT16_X32, /* 0x68 half32 */
+
+    /*  boolean  */
+    gcSHADER_BOOLEAN_X8, /* 0x69 */
+    gcSHADER_BOOLEAN_X16, /* 0x6A */
+    gcSHADER_BOOLEAN_X32, /* 0x6B */
+
+    /* uchar vectors  */
+    gcSHADER_UINT8_X1, /* 0x6C */
+    gcSHADER_UINT8_X2, /* 0x6D */
+    gcSHADER_UINT8_X3, /* 0x6E */
+    gcSHADER_UINT8_X4, /* 0x6F */
+    gcSHADER_UINT8_X8, /* 0x70 */
+    gcSHADER_UINT8_X16, /* 0x71 */
+    gcSHADER_UINT8_X32, /* 0x72 */
+
+    /* char vectors  */
+    gcSHADER_INT8_X1, /* 0x73 */
+    gcSHADER_INT8_X2, /* 0x74 */
+    gcSHADER_INT8_X3, /* 0x75 */
+    gcSHADER_INT8_X4, /* 0x76 */
+    gcSHADER_INT8_X8, /* 0x77 */
+    gcSHADER_INT8_X16, /* 0x78 */
+    gcSHADER_INT8_X32, /* 0x79 */
+
+    /* ushort vectors */
+    gcSHADER_UINT16_X1, /* 0x7A */
+    gcSHADER_UINT16_X2, /* 0x7B */
+    gcSHADER_UINT16_X3, /* 0x7C */
+    gcSHADER_UINT16_X4, /* 0x7D */
+    gcSHADER_UINT16_X8, /* 0x7E */
+    gcSHADER_UINT16_X16, /* 0x7F */
+    gcSHADER_UINT16_X32, /* 0x80 */
+
+    /* short vectors */
+    gcSHADER_INT16_X1, /* 0x81 */
+    gcSHADER_INT16_X2, /* 0x82 */
+    gcSHADER_INT16_X3, /* 0x83 */
+    gcSHADER_INT16_X4, /* 0x84 */
+    gcSHADER_INT16_X8, /* 0x85 */
+    gcSHADER_INT16_X16, /* 0x86 */
+    gcSHADER_INT16_X32, /* 0x87 */
+
+    /* packed data type */
+    /* packed float16 (2 bytes per element) */
+    gcSHADER_FLOAT16_P2, /* 0x88 half2 */
+    gcSHADER_FLOAT16_P3, /* 0x89 half3 */
+    gcSHADER_FLOAT16_P4, /* 0x8A half4 */
+    gcSHADER_FLOAT16_P8, /* 0x8B half8 */
+    gcSHADER_FLOAT16_P16, /* 0x8C half16 */
+    gcSHADER_FLOAT16_P32, /* 0x8D half32 */
+
+    /* packed boolean (1 byte per element) */
+    gcSHADER_BOOLEAN_P2, /* 0x8E bool2 bvec2 */
+    gcSHADER_BOOLEAN_P3, /* 0x8F */
+    gcSHADER_BOOLEAN_P4, /* 0x90 */
+    gcSHADER_BOOLEAN_P8, /* 0x91 */
+    gcSHADER_BOOLEAN_P16, /* 0x92 */
+    gcSHADER_BOOLEAN_P32, /* 0x93 */
+
+    /* uchar vectors (1 byte per element) */
+    gcSHADER_UINT8_P2, /* 0x94 */
+    gcSHADER_UINT8_P3, /* 0x95 */
+    gcSHADER_UINT8_P4, /* 0x96 */
+    gcSHADER_UINT8_P8, /* 0x97 */
+    gcSHADER_UINT8_P16, /* 0x98 */
+    gcSHADER_UINT8_P32, /* 0x99 */
+
+    /* char vectors (1 byte per element) */
+    gcSHADER_INT8_P2, /* 0x9A */
+    gcSHADER_INT8_P3, /* 0x9B */
+    gcSHADER_INT8_P4, /* 0x9C */
+    gcSHADER_INT8_P8, /* 0x9D */
+    gcSHADER_INT8_P16, /* 0x9E */
+    gcSHADER_INT8_P32, /* 0x9F */
+
+    /* ushort vectors (2 bytes per element) */
+    gcSHADER_UINT16_P2, /* 0xA0 */
+    gcSHADER_UINT16_P3, /* 0xA1 */
+    gcSHADER_UINT16_P4, /* 0xA2 */
+    gcSHADER_UINT16_P8, /* 0xA3 */
+    gcSHADER_UINT16_P16, /* 0xA4 */
+    gcSHADER_UINT16_P32, /* 0xA5 */
+
+    /* short vectors (2 bytes per element) */
+    gcSHADER_INT16_P2, /* 0xA6 */
+    gcSHADER_INT16_P3, /* 0xA7 */
+    gcSHADER_INT16_P4, /* 0xA8 */
+    gcSHADER_INT16_P8, /* 0xA9 */
+    gcSHADER_INT16_P16, /* 0xAA */
+    gcSHADER_INT16_P32, /* 0xAB */
+
+    gcSHADER_INTEGER_X8, /* 0xAC */
+    gcSHADER_INTEGER_X16, /* 0xAD */
+    gcSHADER_UINT_X8, /* 0xAE */
+    gcSHADER_UINT_X16, /* 0xAF */
+    gcSHADER_FLOAT_X8, /* 0xB0 */
+    gcSHADER_FLOAT_X16, /* 0xB1 */
+    gcSHADER_INT64_X8, /* 0xB2 */
+    gcSHADER_INT64_X16, /* 0xB3 */
+    gcSHADER_UINT64_X8, /* 0xB4 */
+    gcSHADER_UINT64_X16, /* 0xB5 */
+
+    gcSHADER_FLOAT64_X1, /* 0xB6 */
+    gcSHADER_FLOAT64_X2, /* 0xB7 */
+    gcSHADER_FLOAT64_X3, /* 0xB8 */
+    gcSHADER_FLOAT64_X4, /* 0xB9 */
+    gcSHADER_FLOAT64_2X2, /* 0xBA */
+    gcSHADER_FLOAT64_3X3, /* 0xBB */
+    gcSHADER_FLOAT64_4X4, /* 0xBC */
+    gcSHADER_FLOAT64_2X3, /* 0xBD */
+    gcSHADER_FLOAT64_2X4, /* 0xBE */
+    gcSHADER_FLOAT64_3X2, /* 0xBF */
+    gcSHADER_FLOAT64_3X4, /* 0xC0 */
+    gcSHADER_FLOAT64_4X2, /* 0xC1 */
+    gcSHADER_FLOAT64_4X3, /* 0xC2 */
+    gcSHADER_FLOAT64_X8, /* 0xC3 */
+    gcSHADER_FLOAT64_X16, /* 0xC4 */
+
+    /* OpenGL 4.0 types */
+    gcSHADER_SAMPLER_2D_RECT, /* 0xC5 */
+    gcSHADER_ISAMPLER_2D_RECT, /* 0xC6 */
+    gcSHADER_USAMPLER_2D_RECT, /* 0xC7 */
+    gcSHADER_SAMPLER_2D_RECT_SHADOW, /* 0xC8 */
+    gcSHADER_ISAMPLER_1D_ARRAY, /* 0xC9 */
+    gcSHADER_USAMPLER_1D_ARRAY, /* 0xCA */
+    gcSHADER_ISAMPLER_1D, /* 0xCB */
+    gcSHADER_USAMPLER_1D, /* 0xCC */
+    gcSHADER_SAMPLER_1D_SHADOW, /* 0xCD */
+
+    gcSHADER_UNKONWN_TYPE, /* do not add type after this */
+    gcSHADER_TYPE_COUNT         /* must to change gcvShaderTypeInfo at the
+                                 * same time if you add any new type! */
+}
+gcSHADER_TYPE;
+
+#define isSamplerType(Type)                               ((Type >= gcSHADER_SAMPLER_1D && Type <= gcSHADER_SAMPLER_CUBIC) ||\
+                                                           (Type >= gcSHADER_ISAMPLER_2D && Type <= gcSHADER_SAMPLER_EXTERNAL_OES) ||\
+                                                           (Type >= gcSHADER_SAMPLER_2D_SHADOW && Type <= gcSHADER_USAMPLER_2D_MS_ARRAY) ||\
+                                                           (Type >= gcSHADER_SAMPLER_CUBEMAP_ARRAY && Type <= gcSHADER_USAMPLER_CUBEMAP_ARRAY) || \
+                                                           (Type >= gcSHADER_SAMPLER_BUFFER && Type <= gcSHADER_USAMPLER_BUFFER ) || \
+                                                           (Type >= gcSHADER_SAMPLER_2D_RECT && Type <= gcSHADER_SAMPLER_1D_SHADOW ))
+
+#define isShadowSampler(Type)                             ((Type == gcSHADER_SAMPLER_2D_SHADOW)            || \
+                                                           (Type == gcSHADER_SAMPLER_CUBE_SHADOW)          || \
+                                                           (Type == gcSHADER_SAMPLER_1D_ARRAY_SHADOW)      || \
+                                                           (Type == gcSHADER_SAMPLER_2D_ARRAY_SHADOW)      || \
+                                                           (Type == gcSHADER_SAMPLER_CUBEMAP_ARRAY_SHADOW) || \
+                                                           (Type == gcSHADER_SAMPLER_1D_SHADOW)            || \
+                                                           (Type == gcSHADER_SAMPLER_2D_RECT_SHADOW))
+
+#define isOCLImageType(Type)                              (Type >= gcSHADER_IMAGE_1D_T && Type <= gcSHADER_VIV_GENERIC_IMAGE_T)
+
+#define isOGLImageType(Type)                              ((Type >= gcSHADER_IMAGE_2D && Type <= gcSHADER_VIV_GENERIC_GL_IMAGE) ||\
+                                                           (Type >= gcSHADER_IMAGE_CUBEMAP_ARRAY && Type <= gcSHADER_UIMAGE_CUBEMAP_ARRAY) || \
+                                                           (Type >= gcSHADER_IMAGE_BUFFER && Type <= gcSHADER_UIMAGE_BUFFER))
+
+#define isAtomicType(Type)                                (Type == gcSHADER_ATOMIC_UINT)
+
+#define isNormalType(Type)                                ((!isSamplerType(Type)) && \
+                                                           (!isOCLImageType(Type)) && \
+                                                           (!isOGLImageType(Type)) && \
+                                                           (!isAtomicType(Type)))
+
+typedef enum _gcSHADER_VAR_CATEGORY
+{
+    gcSHADER_VAR_CATEGORY_NORMAL  =  0, /* primitive type and its array */
+    gcSHADER_VAR_CATEGORY_STRUCT, /* structure */
+    gcSHADER_VAR_CATEGORY_BLOCK, /* interface block - uniform or storage */
+    gcSHADER_VAR_CATEGORY_BLOCK_MEMBER, /* member for uniform or storage block */
+    gcSHADER_VAR_CATEGORY_BLOCK_ADDRESS, /* address for uniform or storage block */
+    gcSHADER_VAR_CATEGORY_LOD_MIN_MAX, /* lod min max */
+    gcSHADER_VAR_CATEGORY_LEVEL_BASE_SIZE, /* base level */
+    gcSHADER_VAR_CATEGORY_FUNCTION_INPUT_ARGUMENT, /* function input argument */
+    gcSHADER_VAR_CATEGORY_FUNCTION_OUTPUT_ARGUMENT, /* function output argument */
+    gcSHADER_VAR_CATEGORY_FUNCTION_INOUT_ARGUMENT, /* function inout argument */
+    gcSHADER_VAR_CATEGORY_TOP_LEVEL_STRUCT, /* top level struct, only use for ssbo. */
+    gcSHADER_VAR_CATEGORY_SAMPLE_LOCATION, /* sample location. */
+    gcSHADER_VAR_CATEGORY_ENABLE_MULTISAMPLE_BUFFERS, /* multisample buffers. */
+    gcSHADER_VAR_CATEGORY_TYPE_NAME, /* the name of a type, e.g, a structure type name. */
+    gcSHADER_VAR_CATEGORY_GL_SAMPLER_FOR_IMAGE_T,
+    gcSHADER_VAR_CATEGORY_GL_IMAGE_FOR_IMAGE_T,
+    gcSHADER_VAR_CATEGORY_WORK_THREAD_COUNT, /* the number of concurrent work thread. */
+    gcSHADER_VAR_CATEGORY_WORK_GROUP_COUNT, /* the number of concurrent work group. */
+    gcSHADER_VAR_CATEGORY_WORK_GROUP_ID_OFFSET, /* the workGroupId offset, for multi-GPU only. */
+    gcSHADER_VAR_CATEGORY_GLOBAL_INVOCATION_ID_OFFSET, /* the globalId offset, for multi-GPU only. */
+    gcSHADER_VAR_CATEGORY_VIEW_INDEX,
+}
+gcSHADER_VAR_CATEGORY;
+
+typedef enum _gceTYPE_QUALIFIER
+{
+    gcvTYPE_QUALIFIER_NONE         = 0x0, /* unqualified */
+    gcvTYPE_QUALIFIER_VOLATILE     = 0x1, /* volatile */
+    gcvTYPE_QUALIFIER_RESTRICT     = 0x2, /* restrict */
+    gcvTYPE_QUALIFIER_READ_ONLY    = 0x4, /* readonly */
+    gcvTYPE_QUALIFIER_WRITE_ONLY   = 0x8, /* writeonly */
+    gcvTYPE_QUALIFIER_CONSTANT     = 0x10, /* constant address space */
+    gcvTYPE_QUALIFIER_GLOBAL       = 0x20, /* global address space */
+    gcvTYPE_QUALIFIER_LOCAL        = 0x40, /* local address space */
+    gcvTYPE_QUALIFIER_PRIVATE      = 0x80, /* private address space */
+    gcvTYPE_QUALIFIER_CONST        = 0x100, /* const */
+}gceTYPE_QUALIFIER;
+
+#define gcd_ADDRESS_SPACE_QUALIFIERS  (gcvTYPE_QUALIFIER_CONSTANT | \
+                                       gcvTYPE_QUALIFIER_GLOBAL | \
+                                       gcvTYPE_QUALIFIER_LOCAL | \
+                                       gcvTYPE_QUALIFIER_PRIVATE)
+
+typedef gctUINT16  gctTYPE_QUALIFIER;
+
+/* gcSHADER_PRECISION enumeration. */
+typedef enum _gcSHADER_PRECISION
+{
+    gcSHADER_PRECISION_DEFAULT, /* 0x00 */
+    gcSHADER_PRECISION_LOW, /* 0x01 */
+    gcSHADER_PRECISION_MEDIUM, /* 0x02 */
+    gcSHADER_PRECISION_HIGH, /* 0x03 */
+    gcSHADER_PRECISION_ANY, /* 0x04 */
+}
+gcSHADER_PRECISION;
+
+/* shader layout qualifiers. */
+typedef enum _gceLAYOUT_QUALIFIER
+{
+    gcvLAYOUT_QUALIFIER_NONE                                 = 0x0,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_MULTIPLY               = 0x1,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_OVERLAY                = 0x2,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_DARKEN                 = 0x4,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_LIGHTEN                = 0x8,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_COLORDODGE             = 0x10,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_COLORBURN              = 0x20,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HARDLIGHT              = 0x40,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_SOFTLIGHT              = 0x80,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_DIFFERENCE             = 0x100,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_EXCLUSION              = 0x200,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_HUE                = 0x400,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_SATURATION         = 0x800,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_COLOR              = 0x1000,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_LUMINOSITY         = 0x2000,
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_SCREEN                 = 0x4000,
+
+    gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_ALL_EQUATIONS          = (gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_MULTIPLY|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_SCREEN|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_OVERLAY|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_DARKEN|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_LIGHTEN|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_COLORDODGE|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_COLORBURN|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HARDLIGHT|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_SOFTLIGHT|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_DIFFERENCE|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_EXCLUSION|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_HUE|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_SATURATION|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_COLOR|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_LUMINOSITY),
+
+    gcvLAYOUT_QUALIFIER_BLEND_HW_UNSUPPORT_EQUATIONS_ALL     = gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_ALL_EQUATIONS,
+    gcvLAYOUT_QUALIFIER_BLEND_HW_UNSUPPORT_EQUATIONS_PART0   = (gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_COLORDODGE|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_COLORBURN|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_SOFTLIGHT|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_HUE|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_SATURATION|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_COLOR|
+                                                                gcvLAYOUT_QUALIFIER_BLEND_SUPPORT_HSL_LUMINOSITY),
+}
+gceLAYOUT_QUALIFIER;
+
+/* shader layout qualifiers. */
+typedef enum _gceIMAGE_FORMAT
+{
+    gcIMAGE_FORMAT_DEFAULT  = 0,
+    gcIMAGE_FORMAT_RGBA32F,
+    gcIMAGE_FORMAT_RGBA16F,
+    gcIMAGE_FORMAT_R32F,
+    gcIMAGE_FORMAT_RGBA8,
+    gcIMAGE_FORMAT_RGBA8_SNORM,
+    gcIMAGE_FORMAT_RGBA32I,
+    gcIMAGE_FORMAT_RGBA16I,
+    gcIMAGE_FORMAT_RGBA8I,
+    gcIMAGE_FORMAT_R32I,
+    gcIMAGE_FORMAT_RGBA32UI,
+    gcIMAGE_FORMAT_RGBA16UI,
+    gcIMAGE_FORMAT_RGBA8UI,
+    gcIMAGE_FORMAT_R32UI,
+}
+gceIMAGE_FORMAT;
+
+/* gcSHADER_SHADERMODE enumeration. */
+typedef enum _gcSHADER_SHADERMODE
+{
+    gcSHADER_SHADER_DEFAULT             = 0x00,
+    gcSHADER_SHADER_SMOOTH              = 0x00,
+    gcSHADER_SHADER_FLAT                = 0x01,
+    gcSHADER_SHADER_NOPERSPECTIVE       = 0x02,
+}
+gcSHADER_SHADERMODE;
+
+/* Kernel function property flags. */
+typedef enum _gcePROPERTY_FLAGS
+{
+    gcvPROPERTY_REQD_WORK_GRP_SIZE    = 0x00,
+    gcvPROPERTY_WORK_GRP_SIZE_HINT    = 0x01,
+    gcvPROPERTY_KERNEL_SCALE_HINT     = 0x02,
+    gcvPROPERTY_COUNT
+}
+gceKERNEL_FUNCTION_PROPERTY_FLAGS;
+
+/* HALTI interface block layout qualifiers */
+typedef enum _gceINTERFACE_BLOCK_LAYOUT_ID
+{
+    gcvINTERFACE_BLOCK_NONE      = 0,
+    gcvINTERFACE_BLOCK_SHARED    = 0x01,
+    gcvINTERFACE_BLOCK_STD140    = 0x02,
+    gcvINTERFACE_BLOCK_PACKED    = 0x04,
+    gcvINTERFACE_BLOCK_STD430    = 0x08,
+    gcvINTERFACE_BLOCK_ROW_MAJOR = 0x10,
+}
+gceINTERFACE_BLOCK_LAYOUT_ID;
+
+/* Uniform flags. */
+typedef enum _gceUNIFORM_FLAGS
+{
+    /* special uniform kind */
+    gcvUNIFORM_KIND_NONE                        = 0,
+    gcvUNIFORM_KIND_UBO_ADDRESS                 = 0,
+    gcvUNIFORM_KIND_KERNEL_ARG                  = 1,
+    gcvUNIFORM_KIND_KERNEL_ARG_LOCAL            = 2,
+    gcvUNIFORM_KIND_KERNEL_ARG_SAMPLER          = 3,
+    gcvUNIFORM_KIND_KERNEL_ARG_CONSTANT         = 4,
+    gcvUNIFORM_KIND_KERNEL_ARG_LOCAL_MEM_SIZE   = 5,
+    gcvUNIFORM_KIND_KERNEL_ARG_PRIVATE          = 6,
+    gcvUNIFORM_KIND_LOCAL_ADDRESS_SPACE         = 7,
+    gcvUNIFORM_KIND_PRIVATE_ADDRESS_SPACE       = 8,
+    gcvUNIFORM_KIND_CONSTANT_ADDRESS_SPACE      = 9,
+    gcvUNIFORM_KIND_GLOBAL_SIZE                 = 10,
+    gcvUNIFORM_KIND_LOCAL_SIZE                  = 11,
+    gcvUNIFORM_KIND_NUM_GROUPS                  = 12,
+    gcvUNIFORM_KIND_GLOBAL_OFFSET               = 13,
+    gcvUNIFORM_KIND_WORK_DIM                    = 14,
+    gcvUNIFORM_KIND_TRANSFORM_FEEDBACK_BUFFER   = 15,
+    gcvUNIFORM_KIND_TRANSFORM_FEEDBACK_STATE    = 16,
+    gcvUNIFORM_KIND_PRINTF_ADDRESS              = 17,
+    gcvUNIFORM_KIND_WORKITEM_PRINTF_BUFFER_SIZE = 18,
+    gcvUNIFORM_KIND_STORAGE_BLOCK_ADDRESS       = 19,
+    gcvUNIFORM_KIND_GENERAL_PATCH               = 20,
+    gcvUNIFORM_KIND_IMAGE_EXTRA_LAYER           = 21,
+    gcvUNIFORM_KIND_TEMP_REG_SPILL_ADDRESS      = 22,
+    gcvUNIFORM_KIND_GLOBAL_WORK_SCALE           = 23,
+    gcvUNIFORM_KIND_NUM_GROUPS_FOR_SINGLE_GPU   = 24,
+
+    /* Use this to check if this flag is a special uniform kind. */
+    gcvUNIFORM_FLAG_SPECIAL_KIND_MASK           = 0x1F,
+
+    /* flags */
+    gcvUNIFORM_FLAG_COMPILETIME_INITIALIZED     = 0x000020,
+    gcvUNIFORM_FLAG_LOADTIME_CONSTANT           = 0x000040,
+    gcvUNIFORM_FLAG_IS_ARRAY                    = 0x000080,
+    gcvUNIFORM_FLAG_IS_INACTIVE                 = 0x000100,
+    gcvUNIFORM_FLAG_USED_IN_SHADER              = 0x000200,
+    gcvUNIFORM_FLAG_USED_IN_LTC                 = 0x000400, /* it may be not used in
+                                                          shader, but is used in LTC */
+    gcvUNIFORM_FLAG_INDIRECTLY_ADDRESSED        = 0x000800,
+    gcvUNIFORM_FLAG_MOVED_TO_DUB                = 0x001000,
+    gcvUNIFORM_FLAG_STD140_SHARED               = 0x002000,
+    gcvUNIFORM_FLAG_KERNEL_ARG_PATCH            = 0x004000,
+    gcvUNIFORM_FLAG_SAMPLER_CALCULATE_TEX_SIZE  = 0x008000,
+    gcvUNIFORM_FLAG_DIRECTLY_ADDRESSED          = 0x010000,
+    gcvUNIFORM_FLAG_MOVED_TO_DUBO               = 0x020000,
+    gcvUNIFORM_FLAG_USED_AS_TEXGATHER_SAMPLER   = 0x040000,
+    gcvUNIFORM_FLAG_ATOMIC_COUNTER              = 0x080000,
+    gcvUNIFORM_FLAG_BUILTIN                     = 0x100000,
+    gcvUNIFORM_FLAG_COMPILER_GEN                = 0x200000,
+    gcvUNIFORM_FLAG_IS_POINTER                  = 0x400000, /* a true pointer as defined in the shader source */
+    gcvUNIFORM_FLAG_IS_DEPTH_COMPARISON         = 0x800000,
+    gcvUNIFORM_FLAG_IS_MULTI_LAYER              = 0x1000000,
+    gcvUNIFORM_FLAG_STATICALLY_USED             = 0x2000000,
+    gcvUNIFORM_FLAG_USED_AS_TEXGATHEROFFSETS_SAMPLER = 0x4000000,
+    gcvUNIFORM_FLAG_MOVED_TO_CUBO               = 0x8000000,
+    gcvUNIFORM_FLAG_TREAT_SAMPLER_AS_CONST      = 0x10000000,
+    gcvUNIFORM_FLAG_WITH_INITIALIZER            = 0x20000000,
+    gcvUNIFORM_FLAG_FORCE_ACTIVE                = 0x40000000,
+}
+gceUNIFORM_FLAGS;
+
+#define GetUniformFlagsSpecialKind(f)     ((f) & gcvUNIFORM_FLAG_SPECIAL_KIND_MASK)
+#define isUniformSpecialKind(f)     (((f) & gcvUNIFORM_FLAG_SPECIAL_KIND_MASK) != 0)
+
+/* specific to OPENCL */
+#define isUniformKindBuiltin(k)     ((k) == gcvUNIFORM_KIND_LOCAL_ADDRESS_SPACE       || \
+                                     (k) == gcvUNIFORM_KIND_PRIVATE_ADDRESS_SPACE     || \
+                                     (k) == gcvUNIFORM_KIND_CONSTANT_ADDRESS_SPACE    || \
+                                     (k) == gcvUNIFORM_KIND_KERNEL_ARG_LOCAL_MEM_SIZE || \
+                                     (k) == gcvUNIFORM_KIND_GLOBAL_SIZE               || \
+                                     (k) == gcvUNIFORM_KIND_LOCAL_SIZE                || \
+                                     (k) == gcvUNIFORM_KIND_NUM_GROUPS                || \
+                                     (k) == gcvUNIFORM_KIND_GLOBAL_OFFSET             || \
+                                     (k) == gcvUNIFORM_KIND_WORK_DIM                  || \
+                                     (k) == gcvUNIFORM_KIND_PRINTF_ADDRESS            || \
+                                     (k) == gcvUNIFORM_KIND_GLOBAL_WORK_SCALE         || \
+                                     (k) == gcvUNIFORM_KIND_NUM_GROUPS_FOR_SINGLE_GPU || \
+                                     (k) == gcvUNIFORM_KIND_WORKITEM_PRINTF_BUFFER_SIZE)
+
+#define isUniformKindKernelArg(k)   ((k) == gcvUNIFORM_KIND_KERNEL_ARG                || \
+                                     (k) == gcvUNIFORM_KIND_KERNEL_ARG_LOCAL          || \
+                                     (k) == gcvUNIFORM_KIND_KERNEL_ARG_SAMPLER        || \
+                                     (k) == gcvUNIFORM_KIND_KERNEL_ARG_CONSTANT       || \
+                                     (k) == gcvUNIFORM_KIND_KERNEL_ARG_PRIVATE)
+
+#define GetUniformFlags(u)          ((u)->_flags)
+#define SetUniformFlags(u, flags)   ((u)->_flags = (flags))
+
+#define GetUniformKind(u)           ((gceUNIFORM_FLAGS)((u)->_flags & gcvUNIFORM_FLAG_SPECIAL_KIND_MASK))
+#define SetUniformKind(u, k)        do {                                        \
+                                        gceUNIFORM_FLAGS *_f = &(u)->_flags;    \
+                                        gcmASSERT(isUniformSpecialKind(k));     \
+                                        *_f = (((gctUINT)*_f) & ~gcvUNIFORM_FLAG_SPECIAL_KIND_MASK) | ((k)&gcvUNIFORM_FLAG_SPECIAL_KIND_MASK);       \
+                                    } while (0)
+
+#define UniformHasFlag(u, flag)     (((u)->_flags & (flag)) != 0 )
+#define SetUniformFlag(u, flag)     do {                                    \
+                                        if (isUniformSpecialKind(flag))     \
+                                        {                                   \
+                                            SetUniformKind((u), flag);      \
+                                        } else {                            \
+                                            (u)->_flags |= (gctUINT)(flag); \
+                                        }                                   \
+                                    } while(0)
+
+#define ResetUniformFlag(u, flag)   do {                                \
+                                        gcmASSERT(!isUniformSpecialKind(flag));\
+                                        ((u)->_flags &= ~((gctUINT)flag));       \
+                                    } while (0)
+
+/* kinds */
+#define isUniformTransfromFeedbackState(u)   (GetUniformKind(u) == gcvUNIFORM_KIND_TRANSFORM_FEEDBACK_STATE)
+#define isUniformTransfromFeedbackBuffer(u)  (GetUniformKind(u) == gcvUNIFORM_KIND_TRANSFORM_FEEDBACK_BUFFER)
+#define isUniformImageExtraLayer(u)          (GetUniformKind(u) == gcvUNIFORM_KIND_IMAGE_EXTRA_LAYER)
+#define isUniformWorkDim(u)                  (GetUniformKind(u) == gcvUNIFORM_KIND_WORK_DIM)
+#define isUniformGlobalSize(u)               (GetUniformKind(u) == gcvUNIFORM_KIND_GLOBAL_SIZE)
+#define isUniformLocalSize(u)                (GetUniformKind(u) == gcvUNIFORM_KIND_LOCAL_SIZE)
+#define isUniformNumGroups(u)                (GetUniformKind(u) == gcvUNIFORM_KIND_NUM_GROUPS)
+#define isUniformNumGroupsForSingleGPU(u)    (GetUniformKind(u) == gcvUNIFORM_KIND_NUM_GROUPS_FOR_SINGLE_GPU)
+#define isUniformGlobalOffset(u)             (GetUniformKind(u) == gcvUNIFORM_KIND_GLOBAL_OFFSET)
+#define isUniformLocalAddressSpace(u)        (GetUniformKind(u) == gcvUNIFORM_KIND_LOCAL_ADDRESS_SPACE)
+#define isUniformPrivateAddressSpace(u)      (GetUniformKind(u) == gcvUNIFORM_KIND_PRIVATE_ADDRESS_SPACE)
+#define isUniformConstantAddressSpace(u)     (GetUniformKind(u) == gcvUNIFORM_KIND_CONSTANT_ADDRESS_SPACE)
+#define isUniformKernelArg(u)                (GetUniformKind(u) == gcvUNIFORM_KIND_KERNEL_ARG)
+#define isUniformKernelArgConstant(u)        (GetUniformKind(u) == gcvUNIFORM_KIND_KERNEL_ARG_CONSTANT)
+#define isUniformKernelArgSampler(u)         (GetUniformKind(u) == gcvUNIFORM_KIND_KERNEL_ARG_SAMPLER)
+#define isUniformKernelArgLocal(u)           (GetUniformKind(u) == gcvUNIFORM_KIND_KERNEL_ARG_LOCAL)
+#define isUniformKernelArgLocalMemSize(u)    (GetUniformKind(u) == gcvUNIFORM_KIND_KERNEL_ARG_LOCAL_MEM_SIZE)
+#define isUniformKernelArgPrivate(u)         (GetUniformKind(u) == gcvUNIFORM_KIND_KERNEL_ARG_PRIVATE)
+#define isUniformStorageBlockAddress(u)      (GetUniformKind(u) == gcvUNIFORM_KIND_STORAGE_BLOCK_ADDRESS)
+#define isUniformUBOAddress(u)               ((u)->_varCategory == gcSHADER_VAR_CATEGORY_BLOCK_ADDRESS && \
+                                              GetUniformKind(u) == gcvUNIFORM_KIND_UBO_ADDRESS)
+#define isUniformPrintfAddress(u)            (GetUniformKind(u) == gcvUNIFORM_KIND_PRINTF_ADDRESS)
+#define isUniformWorkItemPrintfBufferSize(u) (GetUniformKind(u) == gcvUNIFORM_KIND_WORKITEM_PRINTF_BUFFER_SIZE)
+#define isUniformTempRegSpillAddress(u)      (GetUniformKind(u) == gcvUNIFORM_KIND_TEMP_REG_SPILL_ADDRESS)
+#define isUniformGlobalWorkScale(u)          (GetUniformKind(u) == gcvUNIFORM_KIND_GLOBAL_WORK_SCALE)
+
+#define hasUniformKernelArgKind(u)          (isUniformKernelArg(u)  ||       \
+                                             isUniformKernelArgLocal(u) ||   \
+                                             isUniformKernelArgSampler(u) || \
+                                             isUniformKernelArgPrivate(u) || \
+                                             isUniformKernelArgConstant(u))
+
+/* Whether the uniform was user-defined or built-in */
+#define isUniformShaderDefined(u)           (((u)->name[0] != '#') ||                                       \
+                                              gcmIS_SUCCESS(gcoOS_StrCmp((u)->name, "#DepthRange.near")) || \
+                                              gcmIS_SUCCESS(gcoOS_StrCmp((u)->name, "#DepthRange.far")) ||  \
+                                              gcmIS_SUCCESS(gcoOS_StrCmp((u)->name, "#DepthRange.diff"))    \
+                                            )
+
+/* flags */
+#define isUniformArray(u)                           (((u)->_flags & gcvUNIFORM_FLAG_IS_ARRAY) != 0)
+#define isUniformInactive(u)                        (((u)->_flags & gcvUNIFORM_FLAG_IS_INACTIVE) != 0)
+#define isUniformImmediate(u)                       (((u)->_flags & gcvUNIFORM_FLAG_COMPILETIME_INITIALIZED) != 0)
+#define isUniformLoadtimeConstant(u)                (((u)->_flags & gcvUNIFORM_FLAG_LOADTIME_CONSTANT) != 0)
+#define isUniformUsedInShader(u)                    (((u)->_flags & gcvUNIFORM_FLAG_USED_IN_SHADER) != 0)
+#define isUniformUsedInLTC(u)                       (((u)->_flags & gcvUNIFORM_FLAG_USED_IN_LTC) != 0)
+#define isUniformSTD140OrShared(u)                  (((u)->_flags & gcvUNIFORM_FLAG_STD140_SHARED) != 0)
+#define isUniformKernelArgPatch(u)                  (((u)->_flags & gcvUNIFORM_FLAG_KERNEL_ARG_PATCH) != 0)
+#define isUniformCompiletimeInitialized(u)          (((u)->_flags & gcvUNIFORM_FLAG_COMPILETIME_INITIALIZED) != 0)
+#define isUniformIndirectlyAddressed(u)             (((u)->_flags & gcvUNIFORM_FLAG_INDIRECTLY_ADDRESSED) != 0)
+#define isUniformDirectlyAddressed(u)               (((u)->_flags & gcvUNIFORM_FLAG_DIRECTLY_ADDRESSED) != 0)
+#define isUniformMovedToDUB(u)                      (((u)->_flags & gcvUNIFORM_FLAG_MOVED_TO_DUB) != 0)
+#define isUniformSamplerCalculateTexSize(u)         (((u)->_flags & gcvUNIFORM_FLAG_SAMPLER_CALCULATE_TEX_SIZE) != 0)
+#define isUniformUsedAsTexGatherSampler(u)          (((u)->_flags & gcvUNIFORM_FLAG_USED_AS_TEXGATHER_SAMPLER) != 0)
+#define isUniformUsedAsTexGatherOffsetsSampler(u)   (((u)->_flags & gcvUNIFORM_FLAG_USED_AS_TEXGATHEROFFSETS_SAMPLER) != 0)
+#define isUniformAtomicCounter(u)                   (((u)->_flags & gcvUNIFORM_FLAG_ATOMIC_COUNTER) != 0)
+#define isUniformBuiltin(u)                         (((u)->_flags & gcvUNIFORM_FLAG_BUILTIN) != 0)
+#define isUniformCompilerGen(u)                     (((u)->_flags & gcvUNIFORM_FLAG_COMPILER_GEN) != 0)
+#define isUniformPointer(u)                         (((u)->_flags & gcvUNIFORM_FLAG_IS_POINTER) != 0)
+#define isUniformMLSampler(u)                       (((u)->_flags & gcvUNIFORM_FLAG_IS_MULTI_LAYER) != 0)
+#define isUniformStaticallyUsed(u)                  (((u)->_flags & gcvUNIFORM_FLAG_STATICALLY_USED) != 0)
+#define isUniformMovedToDUBO(u)                     (((u)->_flags & gcvUNIFORM_FLAG_MOVED_TO_DUBO) != 0)
+#define isUniformMovedToCUBO(u)                     (((u)->_flags & gcvUNIFORM_FLAG_MOVED_TO_CUBO) != 0)
+#define isUniformMovedToAUBO(u)                     (isUniformMovedToDUBO(u) || isUniformMovedToCUBO(u))
+#define isUniformTreatSamplerAsConst(u)             (((u)->_flags & gcvUNIFORM_FLAG_TREAT_SAMPLER_AS_CONST) != 0)
+#define isUniformWithInitializer(u)                 (((u)->_flags & gcvUNIFORM_FLAG_WITH_INITIALIZER) != 0)
+#define isUniformForceActive(u)                     (((u)->_flags & gcvUNIFORM_FLAG_FORCE_ACTIVE) != 0)
+
+#define SetUniformUsedInShader(u)           ((u)->_flags |= gcvUNIFORM_FLAG_USED_IN_SHADER)
+#define ResetUniformUsedInShader(u)         ((u)->_flags &= ~gcvUNIFORM_FLAG_USED_IN_SHADER)
+#define SetUniformUsedInLTC(u)              ((u)->_flags |= gcvUNIFORM_FLAG_USED_IN_LTC)
+#define ResetUniformUsedInLTC(u)            ((u)->_flags &= ~gcvUNIFORM_FLAG_USED_IN_LTC)
+
+#define isUniformNormal(u)                  ((u)->_varCategory == gcSHADER_VAR_CATEGORY_NORMAL)
+#define isUniformStruct(u)                  ((u)->_varCategory == gcSHADER_VAR_CATEGORY_STRUCT)
+#define isUniformBlockMember(u)             ((u)->_varCategory == gcSHADER_VAR_CATEGORY_BLOCK_MEMBER)
+#define isUniformBlockAddress(u)            ((u)->_varCategory == gcSHADER_VAR_CATEGORY_BLOCK_ADDRESS)
+#define isUniformLodMinMax(u)               ((u)->_varCategory == gcSHADER_VAR_CATEGORY_LOD_MIN_MAX)
+#define isUniformLevelBaseSize(u)           ((u)->_varCategory == gcSHADER_VAR_CATEGORY_LEVEL_BASE_SIZE)
+#define isUniformSampleLocation(u)          ((u)->_varCategory == gcSHADER_VAR_CATEGORY_SAMPLE_LOCATION)
+#define isUniformMultiSampleBuffers(u)      ((u)->_varCategory == gcSHADER_VAR_CATEGORY_ENABLE_MULTISAMPLE_BUFFERS)
+#define isUniformGlSamplerForImaget(u)      ((u)->_varCategory == gcSHADER_VAR_CATEGORY_GL_SAMPLER_FOR_IMAGE_T)
+#define isUniformGlImageForImaget(u)        ((u)->_varCategory == gcSHADER_VAR_CATEGORY_GL_IMAGE_FOR_IMAGE_T)
+#define isUniformWorkThreadCount(u)         ((u)->_varCategory == gcSHADER_VAR_CATEGORY_WORK_THREAD_COUNT)
+#define isUniformWorkGroupCount(u)          ((u)->_varCategory == gcSHADER_VAR_CATEGORY_WORK_GROUP_COUNT)
+#define isUniformWorkGroupIdOffset(u)       ((u)->_varCategory == gcSHADER_VAR_CATEGORY_WORK_GROUP_ID_OFFSET)
+#define isUniformGlobalInvocationIdOffset(u)((u)->_varCategory == gcSHADER_VAR_CATEGORY_GLOBAL_INVOCATION_ID_OFFSET)
+#define isUniformViewIndex(u)               ((u)->_varCategory == gcSHADER_VAR_CATEGORY_VIEW_INDEX)
+
+#define isUniformBasicType(u)               (isUniformNormal((u))                   || \
+                                             isUniformBlockMember((u))              || \
+                                             isUniformBlockAddress((u))             || \
+                                             isUniformLodMinMax((u))                || \
+                                             isUniformLevelBaseSize((u))            || \
+                                             isUniformSampleLocation((u))           || \
+                                             isUniformMultiSampleBuffers((u))       || \
+                                             isUniformGlSamplerForImaget((u))       || \
+                                             isUniformGlImageForImaget((u))         || \
+                                             isUniformWorkThreadCount((u))          || \
+                                             isUniformWorkGroupCount((u))           || \
+                                             isUniformWorkGroupIdOffset((u))        || \
+                                             isUniformGlobalInvocationIdOffset((u)))
+
+#define isUniformSampler(u)                 (isUniformNormal(u) && (gcmType_Kind(GetUniformType(u)) == gceTK_SAMPLER))
+
+#define isUniformImage(u)                   (isUniformNormal(u) && (gcmType_Kind(GetUniformType(u)) == gceTK_IMAGE))
+#define isUniformImage2D(uniform)           (((uniform)->u.type == gcSHADER_IMAGE_2D) || ((uniform)->u.type == gcSHADER_IIMAGE_2D) || ((uniform)->u.type == gcSHADER_UIMAGE_2D))
+
+#define isUniformImageT(u)                  (isUniformNormal(u) && (gcmType_Kind(GetUniformType(u)) == gceTK_IMAGE_T))
+
+#define isUniformSamplerBuffer(uniform)     ((uniform->u.type == gcSHADER_SAMPLER_BUFFER) || \
+                                             (uniform->u.type == gcSHADER_ISAMPLER_BUFFER) || \
+                                             (uniform->u.type == gcSHADER_USAMPLER_BUFFER))
+#define isUniformImageBuffer(uniform)       ((uniform->u.type == gcSHADER_IMAGE_BUFFER) || \
+                                             (uniform->u.type == gcSHADER_IIMAGE_BUFFER) || \
+                                             (uniform->u.type == gcSHADER_UIMAGE_BUFFER))
+#define isUniformBuffer(uniform)            (isUniformSamplerBuffer(uniform) || isUniformImageBuffer(uniform))
+
+#define isUniformMatrix(uniform)            ((uniform->u.type == gcSHADER_FLOAT_2X2) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_3X3) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_4X4) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_2X3) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_2X4) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_3X2) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_3X4) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_4X2) || \
+                                             (uniform->u.type == gcSHADER_FLOAT_4X3))
+
+
+typedef enum _gceFEEDBACK_BUFFER_MODE
+{
+  gcvFEEDBACK_INTERLEAVED        = 0x00,
+  gcvFEEDBACK_SEPARATE           = 0x01
+} gceFEEDBACK_BUFFER_MODE;
+
+/* Special register indices. */
+typedef enum _gceBuiltinNameKind
+{
+    gcSL_NONBUILTINGNAME =  0,
+    gcSL_POSITION        = -1,
+    gcSL_POINT_SIZE      = -2,
+    gcSL_COLOR           = -3,
+    gcSL_FRONT_FACING    = -4,
+    gcSL_POINT_COORD     = -5,
+    gcSL_POSITION_W      = -6,
+    gcSL_DEPTH           = -7,
+    gcSL_FOG_COORD       = -8,
+    gcSL_VERTEX_ID       = -9,
+    gcSL_INSTANCE_ID     = -10,
+    gcSL_WORK_GROUP_ID          = -11,
+    gcSL_LOCAL_INVOCATION_ID    = -12,
+    gcSL_GLOBAL_INVOCATION_ID   = -13,
+    gcSL_HELPER_INVOCATION      = -14,
+    gcSL_FRONT_COLOR            = -15,
+    gcSL_BACK_COLOR             = -16,
+    gcSL_FRONT_SECONDARY_COLOR  = -17,
+    gcSL_BACK_SECONDARY_COLOR   = -18,
+    gcSL_TEX_COORD              = -19,
+    gcSL_SUBSAMPLE_DEPTH        = -20, /* internal subsample_depth register */
+    gcSL_PERVERTEX              = -21, /* gl_PerVertex */
+    gcSL_IN                     = -22, /* gl_in */
+    gcSL_OUT                    = -23, /* gl_out */
+    gcSL_INVOCATION_ID          = -24, /* gl_InvocationID */
+    gcSL_PATCH_VERTICES_IN      = -25, /* gl_PatchVerticesIn */
+    gcSL_PRIMITIVE_ID           = -26, /* gl_PrimitiveID */
+    gcSL_TESS_LEVEL_OUTER       = -27, /* gl_TessLevelOuter */
+    gcSL_TESS_LEVEL_INNER       = -28, /* gl_TessLevelInner */
+    gcSL_LAYER                  = -29, /* gl_Layer */
+    gcSL_PRIMITIVE_ID_IN        = -30, /* gl_PrimitiveIDIn */
+    gcSL_TESS_COORD             = -31, /* gl_TessCoord */
+    gcSL_SAMPLE_ID              = -32, /* gl_SampleID */
+    gcSL_SAMPLE_POSITION        = -33, /* gl_SamplePosition */
+    gcSL_SAMPLE_MASK_IN         = -34, /* gl_SampleMaskIn */
+    gcSL_SAMPLE_MASK            = -35, /* gl_SampleMask */
+    gcSL_IN_POSITION            = -36, /* gl_in.gl_Position */
+    gcSL_IN_POINT_SIZE          = -37, /* gl_in.gl_PointSize */
+    gcSL_BOUNDING_BOX           = -38, /* gl_BoundingBox */
+    gcSL_LAST_FRAG_DATA         = -39, /* gl_LastFragData */
+    gcSL_CLUSTER_ID             = -40, /* cluster id */
+    gcSL_BUILTINNAME_COUNT      = 41
+} gceBuiltinNameKind;
+
+/* Special code generation indices. */
+#define gcSL_CG_TEMP1_XY_NO_SRC_SHIFT           108
+#define gcSL_CG_TEMP1_X_NO_SRC_SHIFT            109
+#define gcSL_CG_TEMP2_X_NO_SRC_SHIFT            110
+#define gcSL_CG_TEMP3_X_NO_SRC_SHIFT            111
+#define gcSL_CG_TEMP1                           112
+#define gcSL_CG_TEMP1_X                         113
+#define gcSL_CG_TEMP1_XY                        114
+#define gcSL_CG_TEMP1_XYZ                       115
+#define gcSL_CG_TEMP1_XYZW                      116
+#define gcSL_CG_TEMP2                           117
+#define gcSL_CG_TEMP2_X                         118
+#define gcSL_CG_TEMP2_XY                        119
+#define gcSL_CG_TEMP2_XYZ                       120
+#define gcSL_CG_TEMP2_XYZW                      121
+#define gcSL_CG_TEMP3                           122
+#define gcSL_CG_TEMP3_X                         123
+#define gcSL_CG_TEMP3_XY                        124
+#define gcSL_CG_TEMP3_XYZ                       125
+#define gcSL_CG_TEMP3_XYZW                      126
+#define gcSL_CG_CONSTANT                        127
+
+/* now opcode is encoded with sat,src[0|1]'s neg and abs modifier */
+#define gcdSL_OPCODE_Opcode                  0 : 8
+#define gcdSL_OPCODE_Round                   8 : 3  /* rounding mode */
+#define gcdSL_OPCODE_Sat                    11 : 1  /* target sat modifier */
+#define gcdSL_OPCODE_RES_TYPE               12 : 4
+
+#define gcmSL_OPCODE_GET(Value, Field) \
+    gcmGETBITS(Value, gctUINT16, gcdSL_OPCODE_##Field)
+
+#define gcmSL_OPCODE_SET(Value, Field, NewValue) \
+    gcmSETBITS(Value, gctUINT16, gcdSL_OPCODE_##Field, NewValue)
+
+#define gcmSL_OPCODE_UPDATE(Value, Field, NewValue) \
+        (Value) = gcmSL_OPCODE_SET(Value, Field, NewValue)
+
+/* 4-bit enable bits. */
+#define gcdSL_TARGET_Enable                     0 : 4
+/* Indexed addressing mode of type gcSL_INDEXED. */
+#define gcdSL_TARGET_Indexed                    4 : 3
+/* precision on temp: 1 => high and 0 => medium */
+#define gcdSL_TARGET_Precision                  7 : 3
+/* 4-bit condition of type gcSL_CONDITION. */
+#define gcdSL_TARGET_Condition                  10 : 5
+/* Target format of type gcSL_FORMAT. */
+#define gcdSL_TARGET_Format                    15 : 4
+/* non-zero field to indicate the number of components in target being packed; width of six bits
+ allows number of components to 32. */
+#define gcdSL_TARGET_PackedComponents          19 : 6
+typedef gctUINT32 gctTARGET_t;
+
+#define gcmSL_TARGET_GET(Value, Field) \
+    gcmGETBITS(Value, gctTARGET_t, gcdSL_TARGET_##Field)
+
+#define gcmSL_TARGET_SET(Value, Field, NewValue) \
+    gcmSETBITS(Value, gctTARGET_t, gcdSL_TARGET_##Field, NewValue)
+
+#define SOURCE_is_32BIT   1
+
+/* Register type of type gcSL_TYPE. */
+#define gcdSL_SOURCE_Type                       0 : 3
+/* Indexed register swizzle. */
+#define gcdSL_SOURCE_Indexed                    3 : 3
+/* Source format of type gcSL_FORMAT. */
+#if SOURCE_is_32BIT
+typedef gctUINT32 gctSOURCE_t;
+
+#define gcdSL_SOURCE_Format                     6 : 4
+/* Swizzle fields of type gcSL_SWIZZLE. */
+#define gcdSL_SOURCE_Swizzle                   10 : 8
+#define gcdSL_SOURCE_SwizzleX                  10 : 2
+#define gcdSL_SOURCE_SwizzleY                  12 : 2
+#define gcdSL_SOURCE_SwizzleZ                  14 : 2
+#define gcdSL_SOURCE_SwizzleW                  16 : 2
+
+/* source precision : 1 => high and 0 => medium */
+#define gcdSL_SOURCE_Precision                 18 : 3
+
+/* source modifier */
+#define gcdSL_SOURCE_Neg                       21 : 1
+#define gcdSL_SOURCE_Abs                       22 : 1
+
+/* if this source is parent indexed. Right now only implement this for normal uniform. */
+#define gcdSL_SOURCE_Indexed_Level             23 : 2
+
+/* non-zero field to indicate the number of components in source being packed; width of six bits
+ allows number of components to 32. */
+#define gcdSL_SOURCE_PackedComponents         25 : 6
+
+#else  /* source is 16 bit */
+typedef gctUINT16 gctSOURCE_t;
+
+#define gcdSL_SOURCE_Format                     6 : 2
+/* Swizzle fields of type gcSL_SWIZZLE. */
+#define gcdSL_SOURCE_Swizzle                    8 : 8
+#define gcdSL_SOURCE_SwizzleX                   8 : 2
+#define gcdSL_SOURCE_SwizzleY                  10 : 2
+#define gcdSL_SOURCE_SwizzleZ                  12 : 2
+#define gcdSL_SOURCE_SwizzleW                  14 : 2
+#endif
+
+#define gcmSL_SOURCE_GET(Value, Field) \
+    gcmGETBITS(Value, gctSOURCE_t, gcdSL_SOURCE_##Field)
+
+#define gcmSL_SOURCE_SET(Value, Field, NewValue) \
+    gcmSETBITS(Value, gctSOURCE_t, gcdSL_SOURCE_##Field, NewValue)
+
+/* Index of register. */
+#define gcdSL_INDEX_Index                      0 : 20
+/* Constant value. */
+#define gcdSL_INDEX_ConstValue                20 :  2
+
+#define gcmSL_INDEX_GET(Value, Field) \
+    gcmGETBITS(Value, gctUINT32, gcdSL_INDEX_##Field)
+
+#define gcmSL_INDEX_SET(Value, Field, NewValue) \
+    gcmSETBITS(Value, gctUINT32, gcdSL_INDEX_##Field, NewValue)
+
+#define gcmSL_JMP_TARGET(Value) (Value)->tempIndex
+#define gcmSL_CALL_TARGET(Value) (Value)->tempIndex
+
+#define gcmDummySamplerIdBit          0x2000   /* 14th bit is 1 (MSB for the field gcdSL_INDEX_Index) ??? */
+
+#define gcmMakeDummySamplerId(SID)    ((SID) | gcmDummySamplerIdBit)
+#define gcmIsDummySamplerId(SID)      ((SID) >= gcmDummySamplerIdBit)
+#define gcmGetOriginalSamplerId(SID)  ((SID) & ~gcmDummySamplerIdBit)
+
+#define _MAX_VARYINGS                     32
+#define gcdSL_MIN_TEXTURE_LOD_BIAS       -16
+#define gcdSL_MAX_TEXTURE_LOD_BIAS         6
+
+/* Structure that defines a gcSL instruction. */
+typedef struct _gcSL_INSTRUCTION
+{
+    /* Opcode of type gcSL_OPCODE. */
+    gctUINT16                    opcode;
+
+    /* Indexed register for destination. */
+    gctUINT16                    tempIndexed;
+
+    /* Indexed register for source 0 operand. */
+    gctUINT16                    source0Indexed;
+
+    /* Indexed register for source 1 operand. */
+    gctUINT16                    source1Indexed;
+
+    /* Opcode condition and target write enable bits of type gcSL_TARGET. */
+    gctTARGET_t                  temp;
+
+    /* 16-bit temporary register index, or call/branch target inst. index. */
+    gctUINT32                    tempIndex;
+
+    /* Type of source 0 operand of type gcSL_SOURCE. */
+    gctSOURCE_t                  source0;
+
+    /* 14-bit register index for source 0 operand of type gcSL_INDEX,
+     * must accessed by gcmSL_INDEX_GET(source0Index, Index);
+     * and 2-bit constant value to the base of the Index, must be
+     * accessed by gcmSL_INDEX_GET(source0Index, ConstValue).
+     *
+     * Now we have to change the temp register index to 32 bit due to
+     * the fact that some program may exceed the 14 temp register count
+     * limits!
+     */
+    gctUINT32                    source0Index;
+
+    /* Type of source 1 operand of type gcSL_SOURCE. */
+    gctSOURCE_t                  source1;
+
+    /* 14-bit register index for source 1 operand of type gcSL_INDEX,
+     * must accessed by gcmSL_INDEX_GET(source1Index, Index);
+     * and 2-bit constant value to the base of the Index, must be
+     * accessed by gcmSL_INDEX_GET(source1Index, ConstValue).
+     */
+    gctUINT32                    source1Index;
+
+    gctUINT32                    srcLoc;
+}
+* gcSL_INSTRUCTION;
+
+#define GCSL_SRC_LOC_LINE_OFFSET 16
+#define GCSL_SRC_LOC_COL_MASK 0xffff
+#define GCSL_Build_SRC_LOC(LineNo, StringNo) ((StringNo) | ((LineNo) << GCSL_SRC_LOC_LINE_OFFSET))
+#define GCSL_SRC_LOC_LINENO(loc) (loc >> GCSL_SRC_LOC_LINE_OFFSET)
+#define GCSL_SRC_LOC_COLNO(loc) (loc & GCSL_SRC_LOC_COL_MASK)
+
+#define GetInstOpcode(i)                    ((i)->opcode)
+#define GetInstTemp(i)                      ((i)->temp)
+#define GetInstTempIndex(i)                 ((i)->tempIndex)
+#define GetInstTempIndexed(i)               ((i)->tempIndexed)
+#define GetInstSource0(i)                   ((i)->source0)
+#define GetInstSource0Index(i)              ((i)->source0Index)
+#define GetInstSource0Indexed(i)            ((i)->source0Indexed)
+#define GetInstSource1(i)                   ((i)->source1)
+#define GetInstSource1Index(i)              ((i)->source1Index)
+#define GetInstSource1Indexed(i)            ((i)->source1Indexed)
+
+/******************************************************************************\
+|*********************************** SHADERS **********************************|
+\******************************************************************************/
+#define MAX_LTC_COMPONENTS   4
+
+typedef union _ConstantValueUnion
+{
+    gctBOOL        b;
+    gctUINT8       u8;
+    gctUINT16      u16;
+    gctUINT32      u32;
+    gctUINT64      u64;
+    gctINT8        i8;
+    gctINT16       i16;
+    gctINT32       i32;
+    gctINT64       i64;
+    gctFLOAT       f32;
+} ConstantValueUnion;
+
+typedef struct _LoadtimeConstantValue
+{
+    gcSL_ENABLE          enable;               /* the components enabled, for target value */
+    gctSOURCE_t          sourceInfo;           /* source type, indexed, format and swizzle info */
+    gcSL_FORMAT          elementType;          /* the format of element */
+    gctINT               instructionIndex;     /* the instruction index to the LTC expression in Shader */
+    ConstantValueUnion   v[MAX_LTC_COMPONENTS];
+} LTCValue, *PLTCValue;
+
+typedef enum _gceATTRIBUTE_Flag
+{
+    gcATTRIBUTE_ISTEXTURE           = 0x01,
+    /* Flag to indicate the attribute is a varying packed with othe attribute
+       and is no longer in use in the shader, but it cannot be removed from
+       attribute array due to the shader maybe loaded from saved file and keep
+       the index fro the attributes is needed */
+    gcATTRIBUTE_PACKEDAWAY          = 0x02,
+    /* mark the attribute to always used to avoid be optimized away, it is
+     * useful when doing re-compile, recompiled code cannot change attribute
+     * mapping done by master shader
+     */
+    gcATTRIBUTE_ALWAYSUSED          = 0x04,
+
+    /* mark the attribute to not used based on new RA
+     */
+    gcATTRIBUTE_ISNOTUSED           = 0x08,
+
+    /* Texcoord only for pointsprite */
+    gcATTRIBUTE_POINTSPRITE_TC      = 0x10,
+
+    /* the attribute is per-patch input */
+    gcATTRIBUTE_ISPERPATCH          = 0x20,
+    gcATTRIBUTE_ISZWTEXTURE         = 0x40,
+    gcATTRIBUTE_ISPOSITION          = 0x80,
+    gcATTRIBUTE_ENABLED             = 0x100,
+    gcATTRIBUTE_ISINVARIANT         = 0x200,
+    gcATTRIBUTE_ISPERVERTEXARRAY    = 0x400,
+    gcATTRIBUTE_ISPRECISE           = 0x800,
+    gcATTRIBUTE_ISIOBLOCKMEMBER     = 0x1000,
+    gcATTRIBUTE_ISINSTANCEMEMBER    = 0x2000,
+    gcATTRIBUTE_ISCENTROID          = 0x4000,
+    gcATTRIBUTE_ISSAMPLE            = 0x8000,
+    gcATTRIBUTE_ISPERVERTEXNOTARRAY = 0x10000,
+    gcATTRIBUTE_ISSTATICALLYUSED    = 0x20000,
+    gcATTRIBUTE_ISUSEASINTERPOLATE  = 0x40000,
+
+    /* This attribute is generated by compiler. */
+    gcATTRIBUTE_COMPILERGEN         = 0x80000,
+
+    gcATTRIBUTE_ISDIRECTPOSITION    = 0x100000,
+
+    /* The location is set by driver. */
+    gcATTRIBUTE_LOC_SET_BY_DRIVER   = 0x200000,
+    gcATTRIBUTE_LOC_HAS_ALIAS       = 0x400000, /* aliased with another attribute (same location) */
+
+    gcATTRIBUTE_REG_ALLOCATED       = 0x800000, /* register allocated for this attribute */
+} gceATTRIBUTE_Flag;
+
+#define gcmATTRIBUTE_isTexture(att)             (((att)->flags_ & gcATTRIBUTE_ISTEXTURE) != 0)
+#define gcmATTRIBUTE_packedAway(att)            (((att)->flags_ & gcATTRIBUTE_PACKEDAWAY) != 0)
+#define gcmATTRIBUTE_alwaysUsed(att)            (((att)->flags_ & gcATTRIBUTE_ALWAYSUSED) != 0)
+#define gcmATTRIBUTE_isNotUsed(att)             (((att)->flags_ & gcATTRIBUTE_ISNOTUSED) != 0)
+#define gcmATTRIBUTE_pointspriteTc(att)         (((att)->flags_ & gcATTRIBUTE_POINTSPRITE_TC) != 0)
+#define gcmATTRIBUTE_isPerPatch(att)            (((att)->flags_ & gcATTRIBUTE_ISPERPATCH) != 0)
+#define gcmATTRIBUTE_isZWTexture(att)           (((att)->flags_ & gcATTRIBUTE_ISZWTEXTURE) != 0)
+#define gcmATTRIBUTE_isPosition(att)            (((att)->flags_ & gcATTRIBUTE_ISPOSITION) != 0)
+#define gcmATTRIBUTE_isDirectPosition(att)      (((att)->flags_ & gcATTRIBUTE_ISDIRECTPOSITION) != 0)
+#define gcmATTRIBUTE_enabled(att)               (((att)->flags_ & gcATTRIBUTE_ENABLED) != 0)
+#define gcmATTRIBUTE_isInvariant(att)           (((att)->flags_ & gcATTRIBUTE_ISINVARIANT) != 0)
+#define gcmATTRIBUTE_isPerVertexArray(att)      (((att)->flags_ & gcATTRIBUTE_ISPERVERTEXARRAY) != 0)
+#define gcmATTRIBUTE_isPerVertexNotArray(att)   (((att)->flags_ & gcATTRIBUTE_ISPERVERTEXNOTARRAY) != 0)
+#define gcmATTRIBUTE_isPrecise(att)             (((att)->flags_ & gcATTRIBUTE_ISPRECISE) != 0)
+#define gcmATTRIBUTE_isIOBlockMember(att)       (((att)->flags_ & gcATTRIBUTE_ISIOBLOCKMEMBER) != 0)
+#define gcmATTRIBUTE_isInstanceMember(att)      (((att)->flags_ & gcATTRIBUTE_ISINSTANCEMEMBER) != 0)
+#define gcmATTRIBUTE_isCentroid(att)            (((att)->flags_ & gcATTRIBUTE_ISCENTROID) != 0)
+#define gcmATTRIBUTE_isSample(att)              (((att)->flags_ & gcATTRIBUTE_ISSAMPLE) != 0)
+#define gcmATTRIBUTE_isStaticallyUsed(att)      (((att)->flags_ & gcATTRIBUTE_ISSTATICALLYUSED) != 0)
+#define gcmATTRIBUTE_isCompilerGen(att)         (((att)->flags_ & gcATTRIBUTE_COMPILERGEN) != 0)
+#define gcmATTRIBUTE_isUseAsInterpolate(att)    (((att)->flags_ & gcATTRIBUTE_ISUSEASINTERPOLATE) != 0)
+#define gcmATTRIBUTE_isLocSetByDriver(att)      (((att)->flags_ & gcATTRIBUTE_LOC_SET_BY_DRIVER) != 0)
+#define gcmATTRIBUTE_hasAlias(att)              (((att)->flags_ & gcATTRIBUTE_LOC_HAS_ALIAS) != 0)
+#define gcmATTRIBUTE_isRegAllocated(att)        (((att)->flags_ & gcATTRIBUTE_REG_ALLOCATED) != 0)
+
+#define gcmATTRIBUTE_SetIsTexture(att, v)   \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISTEXTURE) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISTEXTURE))
+#define gcmATTRIBUTE_SetPackedAway(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_PACKEDAWAY) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_PACKEDAWAY))
+
+#define gcmATTRIBUTE_SetAlwaysUsed(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ALWAYSUSED) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ALWAYSUSED))
+
+#define gcmATTRIBUTE_SetNotUsed(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISNOTUSED) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISNOTUSED))
+
+#define gcmATTRIBUTE_SetPointspriteTc(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_POINTSPRITE_TC) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_POINTSPRITE_TC))
+
+#define gcmATTRIBUTE_SetIsPerPatch(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISPERPATCH) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISPERPATCH))
+
+#define gcmATTRIBUTE_SetIsZWTexture(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISZWTEXTURE) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISZWTEXTURE))
+
+#define gcmATTRIBUTE_SetIsPosition(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISPOSITION) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISPOSITION))
+
+#define gcmATTRIBUTE_SetIsDirectPosition(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISDIRECTPOSITION) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISDIRECTPOSITION))
+
+#define gcmATTRIBUTE_SetEnabled(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ENABLED) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ENABLED))
+
+#define gcmATTRIBUTE_SetIsInvariant(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISINVARIANT) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISINVARIANT))
+
+#define gcmATTRIBUTE_SetIsPerVertexArray(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISPERVERTEXARRAY) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISPERVERTEXARRAY))
+
+#define gcmATTRIBUTE_SetIsPerVertexNotArray(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISPERVERTEXNOTARRAY) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISPERVERTEXNOTARRAY))
+
+#define gcmATTRIBUTE_SetIsPrecise(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISPRECISE) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISPRECISE))
+
+#define gcmATTRIBUTE_SetIsIOBlockMember(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISIOBLOCKMEMBER) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISIOBLOCKMEMBER))
+
+#define gcmATTRIBUTE_SetIsInstanceMember(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISINSTANCEMEMBER) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISINSTANCEMEMBER))
+
+#define gcmATTRIBUTE_SetIsCentroid(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISCENTROID) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISCENTROID))
+
+#define gcmATTRIBUTE_SetIsSample(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISSAMPLE) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISSAMPLE))
+
+#define gcmATTRIBUTE_SetIsStaticallyUsed(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISSTATICALLYUSED) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISSTATICALLYUSED))
+
+#define gcmATTRIBUTE_SetIsCompilerGen(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_COMPILERGEN) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_COMPILERGEN))
+
+#define gcmATTRIBUTE_SetIsUseAsInterpolate(att,v )  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_ISUSEASINTERPOLATE) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_ISUSEASINTERPOLATE))
+
+#define gcmATTRIBUTE_SetLocSetByDriver(att, v)  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_LOC_SET_BY_DRIVER) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_LOC_SET_BY_DRIVER))
+
+#define gcmATTRIBUTE_SetLocHasAlias(att, v)  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_LOC_HAS_ALIAS) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_LOC_HAS_ALIAS))
+
+#define gcmATTRIBUTE_SetRegAllocated(att, v)  \
+        ((att)->flags_ = ((att)->flags_ & ~gcATTRIBUTE_REG_ALLOCATED) | \
+                          ((v) == gcvFALSE ? 0 : gcATTRIBUTE_REG_ALLOCATED))
+
+/* Forwarded declaration */
+typedef struct _gcSHADER *              gcSHADER;
+typedef struct _gcATTRIBUTE *           gcATTRIBUTE;
+typedef struct _gcUNIFORM *             gcUNIFORM;
+typedef struct _gcsUNIFORM_BLOCK *      gcsUNIFORM_BLOCK;
+typedef struct _gcsSTORAGE_IO_BLOCK *   gcsSTORAGE_BLOCK;
+typedef struct _gcsIO_BLOCK *           gcsIO_BLOCK;
+typedef struct _gcsINTERFACE_BLOCK_INFO gcsINTERFACE_BLOCK_INFO;
+typedef struct _gcsSHADER_VAR_INFO      gcsSHADER_VAR_INFO;
+typedef struct _gcOUTPUT *              gcOUTPUT;
+typedef struct _gcsFUNCTION *           gcFUNCTION;
+typedef struct _gcsKERNEL_FUNCTION *    gcKERNEL_FUNCTION;
+typedef struct _gcVARIABLE *            gcVARIABLE;
+typedef struct _gcSHADER_LIST *         gcSHADER_LIST;
+typedef struct _gcBINARY_LIST *         gcBINARY_LIST;
+
+struct _gcSHADER_LIST
+{
+    gcSHADER_LIST               next;
+    gctINT                      index;
+    gctINT                      data0;
+    gctINT                      data1;
+};
+
+struct _gcBINARY_LIST
+{
+    gctINT                      index;
+    gctINT                      data0;
+    gctINT                      data1;
+};
+
+/* Structure the defines an attribute (input) for a shader. */
+struct _gcATTRIBUTE
+{
+    /* The object. */
+    gcsOBJECT                    object;
+
+    /* Index of the attribute. */
+    gctUINT16                    index;
+
+    /* Type of the attribute. */
+    gcSHADER_TYPE                type;
+
+    /* Precision of the uniform. */
+    gcSHADER_PRECISION           precision;
+
+    /* Number of array elements for this attribute. */
+    gctINT                       arraySize;
+
+    /* Number of array level. Right now it can only be 0 or 1. */
+    gctINT                       arrayLength;
+
+    /* Flag to indicate this attribute is used as a texture coordinate
+       or packedAway. */
+    gctUINT32                    flags_;
+
+    /* Assigned input register index. */
+    gctINT                       inputIndex;
+
+    /* Flat input or smooth input. */
+    gcSHADER_SHADERMODE          shaderMode;
+
+    /* If other attributes packed to this attribute, we need to change the shade mode for each components. */
+    gcSHADER_SHADERMODE          componentShadeMode[4];
+
+    /* Location index. */
+    gctINT                       location;
+
+    /* Field index. */
+    gctINT                       fieldIndex;
+
+    /* IO block index. */
+    gctINT                       ioBlockIndex;
+
+    /* IO block array index. */
+    gctINT                       ioBlockArrayIndex;
+
+    /* Only used for a IO block member, point to the next element in block. */
+    gctINT16                     nextSibling;
+
+    /* Only used for a IO block member, point to the previous element in block. */
+    gctINT16                     prevSibling;
+
+    /* The variable index of the type name, it is only enabled for a structure member only. */
+    gctINT16                     typeNameVarIndex;
+
+    /* Length of the attribute name. */
+    gctINT                       nameLength;
+
+    /* The attribute name. */
+    char                         name[1];
+};
+
+#define GetATTRObject(a)                    ((a)->object)
+#define GetATTRIndex(a)                     ((a)->index)
+#define GetATTRType(a)                      ((a)->type)
+#define SetATTRType(a, i)                   (GetATTRType(a) = (i))
+#define GetATTRPrecision(a)                 ((a)->precision)
+#define GetATTRArraySize(a)                 ((a)->arraySize)
+#define GetATTRIsArray(a)                   ((a)->arrayLength)
+#define GetATTRFlags(a)                     ((a)->flags_)
+#define GetATTRInputIndex(a)                ((a)->inputIndex)
+#define GetATTRShaderMode(a)                ((a)->shaderMode)
+#define GetATTRComponentShaderModes(a)      ((a)->componentShadeMode)
+#define GetATTRComponentShaderMode(a, i)    ((a)->componentShadeMode[i])
+#define GetATTRLocation(a)                  ((a)->location)
+#define SetATTRLocation(a, l)               (GetATTRLocation(a) = (l))
+#define GetATTRFieldIndex(a)                ((a)->fieldIndex)
+#define GetATTRNameLength(a)                ((a)->nameLength)
+#define GetATTRName(a)                      ((a)->name)
+#define GetATTRIOBlockIndex(a)              ((a)->ioBlockIndex)
+#define SetATTRIOBlockIndex(a, i)           (GetATTRIOBlockIndex(a) = (i))
+#define GetATTRIOBlockArrayIndex(a)         ((a)->ioBlockArrayIndex)
+#define SetATTRIOBlockArrayIndex(a, i)      (GetATTRIOBlockArrayIndex(a) = (i))
+#define GetATTRNextSibling(a)               ((a)->nextSibling)
+#define SetATTRNextSibling(a, i)            (GetATTRNextSibling(a) = (i))
+#define GetATTRPrevSibling(a)               ((a)->prevSibling)
+#define SetATTRPrevSibling(a, i)            (GetATTRPrevSibling(a) = (i))
+#define GetATTRTypeNameVarIndex(a)          ((a)->typeNameVarIndex)
+#define SetATTRTypeNameVarIndex(a, i)       (GetATTRTypeNameVarIndex(a) = (i))
+
+/* Sampel structure, but inside a binary. */
+typedef struct _gcBINARY_ATTRIBUTE
+{
+    /* Index of the attribute. */
+    gctUINT16                     index;
+
+    /* Type for this attribute of type gcATTRIBUTE_TYPE. */
+    gctINT16                      type;
+
+    /* Flag to indicate this attribute is used as a texture coordinate
+       or packedAway. */
+    gctUINT16                     flags1;
+    gctUINT16                     flags2;
+
+    /* Number of array elements for this attribute. */
+    gctINT16                      arraySize;
+
+    /* Number of array level. Right now it can only be 0 or 1. */
+    gctINT16                      arrayLength;
+
+    /* Length of the attribute name. */
+    gctINT16                      nameLength;
+
+    /* precision */
+    gctINT16                      precision;
+
+    /* IO block index. */
+    gctINT16                      ioBlockIndex;
+
+    /* IO block array index. */
+    gctINT16                      ioBlockArrayIndex;
+
+    /* Only used for a IO block member, point to the next element in block. */
+    gctINT16                      nextSibling;
+
+    /* Only used for a IO block member, point to the previous element in block. */
+    gctINT16                      prevSibling;
+
+    /* The variable index of the type name, it is only enabled for a structure member only. */
+    gctINT16                      typeNameVarIndex;
+
+    /* shader mode: flat/smooth/... */
+    gctINT16                      shaderMode;
+
+    /* The attribute name. */
+    char                          name[1];
+}
+* gcBINARY_ATTRIBUTE;
+
+/* Structure that defines inteface information associated with a variable (maybe a gcUNIFORM, gcVARIABLE) for a shader */
+struct _gcsSHADER_VAR_INFO
+{
+    /* Variable category */
+    gcSHADER_VAR_CATEGORY         varCategory;
+
+    /* Data type for this most-inner variable. */
+    gcSHADER_TYPE                 type;
+
+    /* Only used for structure, block, or block member;
+       When used for structure: it points to either first array element for
+       arrayed struct or first struct element if struct is not arrayed;
+
+       When used for block, point to first element in block */
+    gctINT16                      firstChild;
+
+    /* Only used for structure or blocks;
+       When used for structure: it points to either next array element for
+       arrayed struct or next struct element if struct is not arrayed;
+
+       When used for block: it points to the next array element for block, if any */
+    gctINT16                      nextSibling;
+
+    /* Only used for structure or blocks;
+       When used for structure: it points to either prev array element for
+       arrayed struct or prev struct element if struct is not arayed;
+
+       When used for block: it points to the previous array element for block, if any */
+    gctINT16                      prevSibling;
+
+    /* Only used for structure element, point to parent _gcUNIFORM */
+    gctINT16                      parent;
+
+    union
+    {
+        /* Number of element in structure if arraySize of this */
+        /* struct is 1, otherwise, set it to 0 */
+        gctUINT16                 numStructureElement;
+
+        /* Number of element in block */
+        gctUINT16                 numBlockElement;
+    } u;
+
+
+    /* Default block uniform location */
+    gctINT32                      location;
+
+    /* Atomic counter binding */
+    gctINT32                      binding;
+
+    /* Atomic counter offset */
+    gctINT32                      offset;
+
+    gcSHADER_PRECISION            precision  : 8;    /* Precision of the uniform. */
+    gctBOOL                       isArray    : 2;    /* Is variable a true array */
+    gctBOOL                       isLocal    : 2;    /* Is local variable */
+    gctBOOL                       isOutput   : 2;    /* Is output variable */
+    gctBOOL                       isPrecise  : 2;    /* Is precise variable */
+    gctBOOL                       isPerVertex: 2;    /* Is per-vertex */
+    gctBOOL                       isPointer  : 2;    /* Whether the variable is a pointer. */
+
+    /* Number of array elements for this variable(for an array of array, it saves the array size of the higher array). */
+    gctINT                        arraySize;
+
+    /* Number of array level. */
+    gctINT                        arrayCount;
+
+    /* Array size for every array level. */
+    gctINT *                      arraySizeList;
+
+    /* Format of element of the variable. */
+    gcSL_FORMAT                   format;
+
+    /* Format of image */
+    gceIMAGE_FORMAT               imageFormat;
+
+};
+
+#define GetSVICategory(s)                   ((s)->varCategory)
+#define SetSVICategory(s, i)                (GetSVICategory(s) = (i))
+#define GetSVIType(s)                       ((s)->type)
+#define SetSVIType(s, i)                    (GetSVIType(s) = (i))
+#define GetSVIFirstChild(s)                 ((s)->firstChild)
+#define SetSVIFirstChild(s, i)              (GetSVIFirstChild(s) = (i))
+#define GetSVINextSibling(s)                ((s)->nextSibling)
+#define SetSVINextSibling(s, i)             (GetSVINextSibling(s) = (i))
+#define GetSVIPrevSibling(s)                ((s)->prevSibling)
+#define SetSVIPrevSibling(s, i)             (GetSVIPrevSibling(s) = (i))
+#define GetSVIParent(s)                     ((s)->parent)
+#define SetSVIParent(s, i)                  (GetSVIParent(s) = (i))
+#define GetSVINumStructureElement(s)        ((s)->u.numStructureElement)
+#define SetSVINumStructureElement(s, i)     (GetSVINumStructureElement(s) = (i))
+#define GetSVINumBlockElement(s)            ((s)->u.numBlockElement)
+#define SetSVINumBlockElement(s, i)         (GetSVINumBlockElement(s) = (i))
+#define GetSVIPrecision(s)                  ((s)->precision)
+#define SetSVIPrecision(s, i)               (GetSVIPrecision(s) = (i))
+#define GetSVIBinding(s)                    ((s)->binding)
+#define SETSVIBinding(s, b)                 ((s)->binding = (b))
+#define GetSVIIsArray(s)                    ((s)->isArray)
+#define SetSVIIsArray(s, i)                 (GetSVIIsArray(s) = (i))
+#define GetSVIIsLocal(s)                    ((s)->isLocal)
+#define SetSVIIsLocal(s, i)                 (GetSVIIsLocal(s) = (i))
+#define GetSVIIsOutput(s)                   ((s)->isOutput)
+#define SetSVIIsOutput(s, i)                (GetSVIIsOutput(s) = (i))
+#define GetSVIIsPointer(s)                  ((s)->isPointer)
+#define SetSVIIsPointer(s, i)               (GetSVIIsPointer(s) = (i))
+#define GetSVIIsPerVertex(s)                ((s)->isPerVertex)
+#define SetSVIIsPerVertex(s, i)             (GetSVIIsPerVertex(s) = (i))
+#define GetSVIArraySize(s)                  ((s)->arraySize)
+#define SetSVIArraySize(s, i)               (GetSVIArraySize(s) = (i))
+#define GetSVIFormat(s)                     ((s)->format)
+#define SetSVIFormat(s, i)                  (GetSVIFormat(s) = (i))
+#define GetSVIImageFormat(s)                ((s)->imageFormat)
+#define SetSVIImageFormat(s, i)             (GetSVIFormat(s) = (i))
+#define GetSVILocation(s)                   ((s)->location)
+#define SetSVILocation(s, i)                (GetSVILocation(s) = (i))
+
+#define gcvBLOCK_INDEX_DEFAULT           -1
+
+typedef enum _gceInterfaceBlock_Flag
+{
+    gceIB_FLAG_NONE                = 0x00,
+    gceIB_FLAG_UNSIZED             = 0x01, /* last member of storage block is unsized array */
+    gceIB_FLAG_FOR_SHARED_VARIABLE = 0x02, /* block for shared variables */
+    gceIB_FLAG_WITH_INSTANCE_NAME  = 0x04, /* block with a instance name. */
+    gceIB_FLAG_STATICALLY_USED     = 0x08, /* blcok is statically used */
+} gceInterfaceBlock_Flag;
+
+/* Structure that defines a common interface block info for a shader. */
+struct _gcsINTERFACE_BLOCK_INFO
+{
+    /* The object which would denote the block type. */
+    gcsOBJECT                       object;
+
+    gcsSHADER_VAR_INFO              variableInfo;
+
+    /* Interface block index */
+    gctINT16                        blockIndex;
+
+    /* If interface block is an array, use this field to record the array index of this
+    ** block array element
+    */
+    gctINT16                        arrayIndex;
+
+    /* Index of the uniform to keep the base address. */
+    gctINT16                        index;
+
+    /* temp register to contain the base address of shared variable storage block*/
+    gctINT                          _sharedVariableBaseAddress;
+
+    /* interface block flag */
+    gceInterfaceBlock_Flag          flags;
+
+    /* Memory layout */
+    gceINTERFACE_BLOCK_LAYOUT_ID    memoryLayout;
+
+    /* block size in bytes */
+    gctUINT32                       blockSize;
+
+    /* binding point */
+    gctINT32                        binding;
+};
+
+#define GetIBIObject(ibi)                    (&((ibi)->object))
+#define SetIBIObject(ibi, i)                 (*GetIBIObject(ibi) = (i))
+#define GetIBIShaderVarInfo(ibi)             (&((ibi)->variableInfo))
+#define SetIBIShaderVarInfo(ibi, i)          (*GetIBIShaderVarInfo(ibi) = (i))
+#define GetIBIBlockIndex(ibi)                ((ibi)->blockIndex)
+#define SetIBIBlockIndex(ibi, i)             (GetIBIBlockIndex(ibi) = (i))
+#define GetIBIArrayIndex(ibi)                ((ibi)->arrayIndex)
+#define SetIBIArrayIndex(ibi, i)             (SetIBIArrayIndex(ibi) = (i))
+#define GetIBIIndex(ibi)                     ((ibi)->index)
+#define SetIBIIndex(ibi, i)                  (GetIBIIndex(ibi) = (i))
+#define GetIBISharedVariableBaseAddress(ibi) ((ibi)->_sharedVariableBaseAddress)
+#define SetIBISharedVariableBaseAddress(ibi, i) (GetIBISharedVariableBaseAddress(ibi) = (i))
+#define GetIBIFlag(ibi)                      ((ibi)->flags)
+#define SetIBIFlag(ibi, i)                   do { (ibi)->flags |= (gceInterfaceBlock_Flag)(i); } while (0)
+#define HasIBIFlag(ibi, i)                   ((ibi)->flags & (gceInterfaceBlock_Flag)(i))
+#define GetIBIMemoryLayout(ibi)              ((ibi)->memoryLayout)
+#define SetIBIMemoryLayout(ibi, i)           (GetIBIMemoryLayout(ibi) = (i))
+#define GetIBIBlockSize(ibi)                 ((ibi)->blockSize)
+#define SetIBIBlockSize(ibi, i)              (GetIBIBlockSize(ibi) = (i))
+#define GetIBIBinding(ibi)                   ((ibi)->binding)
+#define SetIBIBinding(ibi, i)                (GetIBIBinding(ibi) = (i))
+
+#define isIBIUniformBlock(ibi)               (GetIBIObject(ibi)->type == gcvOBJ_UNIFORM_BLOCK)
+#define isIBIStorageBlock(ibi)               (GetIBIObject(ibi)->type == gcvOBJ_STORAGE_BLOCK)
+
+#define GetIBICategory(s)                   GetSVICategory(GetIBIShaderVarInfo(s))
+#define SetIBICategory(s, i)                SetSVICategory(GetIBIShaderVarInfo(s), (i))
+#define GetIBIType(s)                       GetSVIType(GetIBIShaderVarInfo(s))
+#define SetIBIType(s, i)                    SetSVIType(GetIBIShaderVarInfo(s), (i))
+#define GetIBIFirstChild(s)                 GetSVIFirstChild(GetIBIShaderVarInfo(s))
+#define SetIBIFirstChild(s, i)              SetSVIFirstChild(GetIBIShaderVarInfo(s), (i))
+#define GetIBINextSibling(s)                GetSVINextSibling(GetIBIShaderVarInfo(s))
+#define SetIBINextSibling(s, i)             SetSVINextSibling(GetIBIShaderVarInfo(s), (i))
+#define GetIBIPrevSibling(s)                GetSVIPrevSibling(GetIBIShaderVarInfo(s))
+#define SetIBIPrevSibling(s, i)             SetSVIPrevSibling(GetIBIShaderVarInfo(s), (i))
+#define GetIBIParent(s)                     GetSVIParent(GetIBIShaderVarInfo(s))
+#define SetIBIParent(s, i)                  SetSVIParent(GetIBIShaderVarInfo(s), (i))
+#define GetIBINumStructureElement(s)        GetSVINumStructureElement(GetIBIShaderVarInfo(s))
+#define SetIBINumStructureElement(s, i)     SetSVINumStructureElement(GetIBIShaderVarInfo(s), (i))
+#define GetIBINumBlockElement(s)            GetSVINumBlockElement(GetIBIShaderVarInfo(s))
+#define SetIBINumBlockElement(s, i)         SetSVINumBlockElement(GetIBIShaderVarInfo(s), (i))
+#define GetIBIPrecision(s)                  GetSVIPrecision(GetIBIShaderVarInfo(s))
+#define SetIBIPrecision(s, i)               SetSVIPrecision(GetIBIShaderVarInfo(s), (i))
+#define GetIBIIsArray(s)                    GetSVIIsArray(GetIBIShaderVarInfo(s))
+#define SetIBIIsArray(s, i)                 SetSVIIsArray(GetIBIShaderVarInfo(s), (i))
+#define GetIBIArraySize(s)                  GetSVIArraySize(GetIBIShaderVarInfo(s))
+#define SetIBIArraySize(s, i)               SetSVIArraySize(GetIBIShaderVarInfo(s), (i))
+#define GetIBILocation(s)                   GetSVILocation(GetIBIShaderVarInfo(s))
+#define SetIBILocation(s, i)                SetSVILocation(GetIBIShaderVarInfo(s), (i))
+
+/* Structure that defines a uniform block for a shader. */
+struct _gcsUNIFORM_BLOCK
+{
+    gcsINTERFACE_BLOCK_INFO         interfaceBlockInfo;
+
+    /* Shader type for this uniform. Set this at the end of link. */
+    gcSHADER_KIND                   shaderKind;
+
+    gctBOOL                         _useLoadInst; /* indicate to use LOAD */
+    gctBOOL                         _finished;
+
+    /* number of uniforms in block */
+    gctUINT32                       uniformCount;
+
+    /* array of pointers to uniforms in block */
+    gcUNIFORM                       *uniforms;
+
+    /* If a uniform is used on both VS and PS,
+    ** the index of this uniform on the other shader would be saved by this.
+    */
+    gctINT16                        matchIndex;
+
+    /* Length of the uniform block name. */
+    gctINT                          nameLength;
+
+    /* The uniform block name. */
+    char                            name[1];
+};
+
+#define GetUBInterfaceBlockInfo(u)          (&((u)->interfaceBlockInfo))
+#define SetUBInterfaceBlockInfo(u, i)       (*GetUBInterfaceBlockInfo(u) = (i))
+#define GetUBObject(u)                      (&(GetUBInterfaceBlockInfo(u)->object))
+#define SetUBObject(u, i)                   (*GetUBObject(u) = (i))
+#define GetUBUseLoadInst(u)                 ((u)->_useLoadInst)
+#define SetUBUseLoadInst(u, i)              (GetUBUseLoadInst(u), (i))
+#define GetUBFinished(u)                    ((u)->_finished)
+#define SetUBFinished(u, i)                 (GetUBFinished(u), (i))
+#define GetUBShaderVarInfo(u)               (&(GetUBInterfaceBlockInfo(u)->variableInfo))
+#define SetUBShaderVarInfo(u, i)            (*GetUBShaderVarInfo(u) = (i))
+#define GetUBBlockIndex(u)                  (GetUBInterfaceBlockInfo(u)->blockIndex)
+#define SetUBBlockIndex(u, i)               (GetUBBlockIndex(u) = (i))
+#define GetUBIndex(u)                       (GetUBInterfaceBlockInfo(u)->index)
+#define SetUBIndex(u, i)                    (GetUBIndex(u) = (i))
+#define GetUBMemoryLayout(u)                (GetUBInterfaceBlockInfo(u)->memoryLayout)
+#define SetUBMemoryLayout(u, i)             (GetUBMemoryLayout(u) = (i))
+#define GetUBBlockSize(u)                   (GetUBInterfaceBlockInfo(u)->blockSize)
+#define SetUBBlockSize(u, i)                (GetUBBlockSize(u) = (i))
+#define GetUBBinding(u)                     (GetUBInterfaceBlockInfo(u)->binding)
+#define SetUBBinding(u, i)                  (GetUBBinding(u) = (i))
+#define GetUBUniformCount(u)                ((u)->uniformCount)
+#define SetUBUniformCount(u, i)             (GetUBUniformCount(u) = (i))
+#define GetUBUniforms(u)                    ((u)->uniforms)
+#define SetUBUniforms(u, i)                 (GetUBUniforms(u) = (i))
+#define GetUBMatchIndex(u)                  ((u)->matchIndex)
+#define SetUBMatchIndex(u, i)               (GetUBMatchIndex(u) = (i))
+#define GetUBArrayIndex(u)                  (GetUBInterfaceBlockInfo(u)->arrayIndex)
+#define SetUBArrayIndex(u, i)               (GetUBArrayIndex(u) = (i))
+#define GetUBNameLength(u)                  ((u)->nameLength)
+#define SetUBNameLength(u, i)               (GetUBNameLength(u) = (i))
+#define GetUBName(u)                        ((u)->name)
+#define SetUBName(u, i)                     (GetUBName(u) = (i))
+#define GetUBShaderKind(u)                  ((u)->shaderKind)
+#define SetUBShaderKind(u, i)               (GetUBShaderKind(u) = (i))
+#define GetUBFlag(u)                        GetIBIFlag(GetUBInterfaceBlockInfo(u))
+#define SetUBFlag(u, i)                     SetIBIFlag(GetUBInterfaceBlockInfo(u), (i))
+
+#define GetUBCategory(s)                   GetSVICategory(GetUBShaderVarInfo(s))
+#define SetUBCategory(s, i)                SetSVICategory(GetUBShaderVarInfo(s), (i))
+#define GetUBType(s)                       GetSVIType(GetUBShaderVarInfo(s))
+#define SetUBType(s, i)                    SetSVIType(GetUBShaderVarInfo(s), (i))
+#define GetUBFirstChild(s)                 GetSVIFirstChild(GetUBShaderVarInfo(s))
+#define SetUBFirstChild(s, i)              SetSVIFirstChild(GetUBShaderVarInfo(s), (i))
+#define GetUBNextSibling(s)                GetSVINextSibling(GetUBShaderVarInfo(s))
+#define SetUBNextSibling(s, i)             SetSVINextSibling(GetUBShaderVarInfo(s), (i))
+#define GetUBPrevSibling(s)                GetSVIPrevSibling(GetUBShaderVarInfo(s))
+#define SetUBPrevSibling(s, i)             SetSVIPrevSibling(GetUBShaderVarInfo(s), (i))
+#define GetUBParent(s)                     GetSVIParent(GetUBShaderVarInfo(s))
+#define SetUBParent(s, i)                  SetSVIParent(GetUBShaderVarInfo(s), (i))
+#define GetUBNumStructureElement(s)        GetSVINumStructureElement(GetUBShaderVarInfo(s))
+#define SetUBNumStructureElement(s, i)     SetSVINumStructureElement(GetUBShaderVarInfo(s), (i))
+#define GetUBNumBlockElement(s)            GetSVINumBlockElement(GetUBShaderVarInfo(s))
+#define SetUBNumBlockElement(s, i)         SetSVINumBlockElement(GetUBShaderVarInfo(s), (i))
+#define GetUBPrecision(s)                  GetSVIPrecision(GetUBShaderVarInfo(s))
+#define SetUBPrecision(s, i)               SetSVIPrecision(GetUBShaderVarInfo(s), (i))
+#define GetUBIsArray(s)                    GetSVIIsArray(GetUBShaderVarInfo(s))
+#define SetUBIsArray(s, i)                 SetSVIIsArray(GetUBShaderVarInfo(s), (i))
+#define GetUBArraySize(s)                  GetSVIArraySize(GetUBShaderVarInfo(s))
+#define SetUBArraySize(s, i)               SetSVIArraySize(GetUBShaderVarInfo(s), (i))
+
+/* Structure that defines a uniform block for a shader. */
+typedef struct _gcBINARY_UNIFORM_BLOCK
+{
+    /* Memory layout */
+    gctUINT16                       memoryLayout;
+
+    /* block size in bytes */
+    gctUINT16                       blockSize;
+
+    /* Number of element in block */
+    gctUINT16                       numBlockElement;
+
+    /* points to first element in block */
+    gctINT16                        firstChild;
+
+    /* points to the next array element for block, if any */
+    gctINT16                        nextSibling;
+
+    /* points to the previous array element for block, if any */
+    gctINT16                        prevSibling;
+
+    /* Index of the uniform to keep the base address. */
+    gctINT16                        index;
+
+    /* Index of the uniform to keep the base address. */
+    gctINT16                        arrayIndex;
+
+    /* Length of the uniform block name. */
+    gctINT16                        nameLength;
+
+    /* binding point */
+    char                            binding[sizeof(gctINT32)];
+
+    /* The uniform block name. */
+    char                            name[1];
+}
+*gcBINARY_UNIFORM_BLOCK;
+
+/* Structure that defines a storage block for a shader. */
+struct _gcsSTORAGE_IO_BLOCK
+{
+    gcsINTERFACE_BLOCK_INFO         interfaceBlockInfo;
+
+    /* number of variables in block */
+    gctUINT32                       variableCount;
+
+    /* array of pointers to variables in block */
+    gcVARIABLE                      *variables;
+
+    /* If a storage buffer object is used on both VS and PS,
+    ** the index of this SBO on the other shader would be saved by this.
+    */
+    gctINT16                        matchIndex;
+
+    /* Length of the block name. */
+    gctINT                          nameLength;
+
+    /* The block name. */
+    char                            name[1];
+};
+
+/* Structure that defines a IO block for a shader. */
+struct _gcsIO_BLOCK
+{
+    gcsINTERFACE_BLOCK_INFO         interfaceBlockInfo;
+
+    /* Length of the block name. */
+    gctINT                          nameLength;
+
+    /* Length of the instance name. */
+    gctINT                          instanceNameLength;
+
+    /* The name, it would be BlockName{.instanceName} */
+    char                            name[1];
+};
+
+#define GetSBInterfaceBlockInfo(s)          (&((s)->interfaceBlockInfo))
+#define SetSBInterfaceBlockInfo(s, i)       (*GetSBInterfaceBlockInfo(s) = (i))
+#define GetSBObject(s)                      (&(GetSBInterfaceBlockInfo(s)->object))
+#define SetSBObject(s, i)                   (*GetSBObject(s) = (i))
+#define GetSBShaderVarInfo(s)               (&(GetSBInterfaceBlockInfo(s)->variableInfo))
+#define SetSBShaderVarInfo(s, i)            (*GetSBShaderVarInfo(s) = (i))
+#define GetSBBlockIndex(s)                  (GetSBInterfaceBlockInfo(s)->blockIndex)
+#define SetSBBlockIndex(s, i)               (GetSBBlockIndex(s) = (i))
+#define GetSBIndex(s)                       (GetSBInterfaceBlockInfo(s)->index)
+#define SetSBIndex(s, i)                    (GetSBIndex(s) = (i))
+#define GetSBSharedVariableBaseAddress(s)   (GetSBInterfaceBlockInfo(s)->_sharedVariableBaseAddress)
+#define SetSBSharedVariableBaseAddress(s, i) (GetSBSharedVariableBaseAddress(s) = (i))
+
+#define GetSBMemoryLayout(s)                (GetSBInterfaceBlockInfo(s)->memoryLayout)
+#define SetSBMemoryLayout(s, i)             (GetSBMemoryLayout(s) = (i))
+#define GetSBBlockSize(s)                   (GetSBInterfaceBlockInfo(s)->blockSize)
+#define SetSBBlockSize(s, i)                (GetSBBlockSize(s) = (i))
+#define GetSBBinding(s)                     (GetSBInterfaceBlockInfo(s)->binding)
+#define SetSBBinding(s, i)                  (GetSBBinding(s) = (i))
+#define GetSBVariableCount(s)               ((s)->variableCount)
+#define SetSBVariableCount(s, i)            (GetSBVariableCount(s) = (i))
+#define GetSBVariables(s)                   ((s)->variables)
+#define GetSBVariable(s, i)                 ((s)->variables[(i)])
+#define SetSBVariables(s, i)                (GetSBVariables(s) = (i))
+#define GetSBNameLength(s)                  ((s)->nameLength)
+#define SetSBNameLength(s, i)               (GetSBNameLength(s) = (i))
+#define GetSBName(s)                        ((s)->name)
+#define SetSBName(s, i)                     (GetSBName(s) = (i))
+#define GetSBInstanceNameLength(s)          ((s)->instanceNameLength)
+#define SetSBInstanceNameLength(s, i)       (GetSBInstanceNameLength(s) = (i))
+#define GetSBMatchIndex(s)                  ((s)->matchIndex)
+#define SetSBMatchIndex(s, i)               (GetSBMatchIndex(s) = (i))
+#define GetSBFlag(s)                        GetIBIFlag(GetSBInterfaceBlockInfo(s))
+#define SetSBFlag(s, i)                     SetIBIFlag(GetSBInterfaceBlockInfo(s), (i))
+#define GetSBCategory(s)                   GetSVICategory(GetSBShaderVarInfo(s))
+#define SetSBCategory(s, i)                SetSVICategory(GetSBShaderVarInfo(s), (i))
+#define GetSBType(s)                       GetSVIType(GetSBShaderVarInfo(s))
+#define SetSBType(s, i)                    SetSVIType(GetSBShaderVarInfo(s), (i))
+#define GetSBFirstChild(s)                 GetSVIFirstChild(GetSBShaderVarInfo(s))
+#define SetSBFirstChild(s, i)              SetSVIFirstChild(GetSBShaderVarInfo(s), (i))
+#define GetSBNextSibling(s)                GetSVINextSibling(GetSBShaderVarInfo(s))
+#define SetSBNextSibling(s, i)             SetSVINextSibling(GetSBShaderVarInfo(s), (i))
+#define GetSBPrevSibling(s)                GetSVIPrevSibling(GetSBShaderVarInfo(s))
+#define SetSBPrevSibling(s, i)             SetSVIPrevSibling(GetSBShaderVarInfo(s), (i))
+#define GetSBParent(s)                     GetSVIParent(GetSBShaderVarInfo(s))
+#define SetSBParent(s, i)                  SetSVIParent(GetSBShaderVarInfo(s), (i))
+#define GetSBNumStructureElement(s)        GetSVINumStructureElement(GetSBShaderVarInfo(s))
+#define SetSBNumStructureElement(s, i)     SetSVINumStructureElement(GetSBShaderVarInfo(s), (i))
+#define GetSBNumBlockElement(s)            GetSVINumBlockElement(GetSBShaderVarInfo(s))
+#define SetSBNumBlockElement(s, i)         SetSVINumBlockElement(GetSBShaderVarInfo(s), (i))
+#define GetSBPrecision(s)                  GetSVIPrecision(GetSBShaderVarInfo(s))
+#define SetSBPrecision(s, i)               SetSVIPrecision(GetSBShaderVarInfo(s), (i))
+#define GetSBIsArray(s)                    GetSVIIsArray(GetSBShaderVarInfo(s))
+#define SetSBIsArray(s, i)                 SetSVIIsArray(GetSBShaderVarInfo(s), (i))
+#define GetSBArraySize(s)                  GetSVIArraySize(GetSBShaderVarInfo(s))
+#define SetSBArraySize(s, i)               SetSVIArraySize(GetSBShaderVarInfo(s), (i))
+
+/* Structure that defines a storage block for a shader. */
+typedef struct _gcBINARY_STORAGE_IO_BLOCK
+{
+    /* Memory layout */
+    gctUINT16                       memoryLayout;
+
+    /* flags */
+    gctUINT16                       flags;
+
+    /* block size in bytes */
+    gctUINT16                       blockSize;
+
+    /* Number of element in block */
+    gctUINT16                       numBlockElement;
+
+    /* points to first element in block */
+    gctINT16                        firstChild;
+
+    /* points to the next array element for block, if any */
+    gctINT16                        nextSibling;
+
+    /* points to the previous array element for block, if any */
+    gctINT16                        prevSibling;
+
+    /* Index of the uniform to keep the base address. */
+    gctINT16                        index;
+
+    /* Length of the storage block name. */
+    gctINT16                        nameLength;
+
+    /* Length of the instance name. */
+    gctINT16                        instanceNameLength;
+
+    /* binding point */
+    char                            binding[sizeof(gctINT32)];
+
+    /* The storage block name. */
+    char                            name[1];
+}
+*gcBINARY_STORAGE_BLOCK;
+
+typedef struct _gcBINARY_STORAGE_IO_BLOCK * gcBINARY_IO_BLOCK;
+
+typedef enum _gcUNIFORM_RES_OP_FLAG
+{
+    gcUNIFORM_RES_OP_FLAG_NONE        = 0x0000,
+    gcUNIFORM_RES_OP_FLAG_TEXLD       = 0x0001,
+    gcUNIFORM_RES_OP_FLAG_TEXLD_BIAS  = 0x0002,
+    gcUNIFORM_RES_OP_FLAG_TEXLD_LOD   = 0x0004,
+    gcUNIFORM_RES_OP_FLAG_TEXLD_GRAD  = 0x0008,
+    gcUNIFORM_RES_OP_FLAG_TEXLDP      = 0x0010,
+    gcUNIFORM_RES_OP_FLAG_TEXLDP_GRAD = 0x0020,
+    gcUNIFORM_RES_OP_FLAG_TEXLDP_BIAS = 0x0040,
+    gcUNIFORM_RES_OP_FLAG_TEXLDP_LOD  = 0x0080,
+    gcUNIFORM_RES_OP_FLAG_FETCH       = 0x0100,
+    gcUNIFORM_RES_OP_FLAG_FETCH_MS    = 0x0200,
+    gcUNIFORM_RES_OP_FLAG_GATHER      = 0x0400,
+    gcUNIFORM_RES_OP_FLAG_GATHER_PCF  = 0x0800,
+    gcUNIFORM_RES_OP_FLAG_LODQ        = 0x1000,
+}gcUNIFORM_RES_OP_FLAG;
+
+/* Structure that defines an uniform (constant register) for a shader. */
+struct _gcUNIFORM
+{
+    /* The object. */
+    gcsOBJECT                       object;
+
+    /* Index of the uniform. */
+    gctUINT16                       index;
+
+    /* Uniform block index: Default block index = -1 */
+    gctINT16                        blockIndex;
+
+    /* Corresponding Index of Program's GLUniform */
+    gctINT16                        glUniformIndex;
+
+    /* Index to image sampler for OpenCL */
+    gctUINT16                       imageSamplerIndex;
+
+    /* If a uniform is used on both VS and PS,
+    ** the index of this uniform on the other shader would be saved by this.
+    */
+    gctINT16                        matchIndex;
+
+    /* Variable category */
+    gcSHADER_VAR_CATEGORY           _varCategory : 8;
+
+    /* Physically assigned values. */
+    gctUINT8                        swizzle      : 8;
+
+    /* Shader type for this uniform. Set this at the end of link. */
+    gcSHADER_KIND                   shaderKind : 5;
+
+        /* memory order of matrices */
+    gctBOOL                         isRowMajor : 2;
+
+    /* Whether the uniform is a pointer. */
+    gctBOOL                         isPointer  : 2;
+
+
+    /*
+    ** 1) If this uniform is a normal constant uniform, save the const index in physical.
+    ** 2) If this uniform is a normal texture uniform, save the sampler index in physical.
+    ** 3) If this uniform is a sampler_buffer, save the const index in physical,
+    **    save the sampler index in samplerPhysical
+    */
+    gctINT                          physical;
+    gctINT                          samplerPhysical;
+    gctUINT32                       address;
+    gctUINT32                       RAPriority;
+
+    /* Flags. */
+    gceUNIFORM_FLAGS                _flags;
+
+    gcUNIFORM_RES_OP_FLAG           resOpFlag;
+
+    /* stride on array or matrix */
+    gctINT32                        arrayStride;
+    gctINT16                        matrixStride;
+
+    /* Number of array elements for this uniform. */
+    gctINT                          arraySize;
+    /* Number of array elements that are used in the shader. */
+    gctINT                          usedArraySize;
+
+    /* Number of array level. */
+    gctINT                          arrayLengthCount;
+
+    /* Array size for every array level. */
+    gctINT *                        arrayLengthList;
+
+    /* offset from uniform block's base address */
+    gctINT32                        offset;
+
+    union
+    {
+        /* Data type for this most-inner variable. */
+        gcSHADER_TYPE               type;
+
+        /* Number of element in structure if arraySize of this */
+        /* struct is 1, otherwise, set it to 0 */
+        gctUINT16                   numStructureElement;
+
+        /* Number of elements in block */
+        gctUINT16                   numBlockElement;
+    }
+    u;
+
+    /* type qualifier */
+    gctTYPE_QUALIFIER               qualifier;
+
+    /* Precision of the uniform. */
+    gcSHADER_PRECISION              precision;
+
+    /* ES31 explicit binding for opaque uniforms, 0 if not specify. */
+    gctINT                          binding;
+
+    /* ES31 explicit location for default block uniforms;  -1 if not specify. */
+    gctINT                          location;
+
+    /* Whether the uniform is part of model view projectoin matrix. */
+    gctINT                          modelViewProjection;
+
+    /* Format of element of the uniform shaderType. */
+    gcSL_FORMAT                     format;
+
+    /* Format of element of the uniform shaderType. */
+    gctINT                          vectorSize;
+
+    /* Offset to typeNameBuffer in shader to locate the non basic type name of uniform shaderType.
+       For basic type: the value is -1
+    */
+    gctINT                          typeNameOffset;
+
+    /* Compile-time constant value, */
+    gcsValue                        initializer;
+
+    /* ES31 explicit base address uniform for atomic counter;  -1 if not specify. */
+    gctINT16                        baseBindingIdx;
+
+    /* Dummy-uniform index for LTC uniform, -1 for non-ltc uniforms. */
+    gctINT16                        dummyUniformIndex;
+
+    /* Only used for structure or blocks;
+       When used for structure, point to either first array element for
+       arrayed struct or first struct element if struct is not arrayed
+
+       When used for block, point to first element in block */
+    gctINT16                        firstChild;
+
+    /* Only used for structure or blocks;
+       When used for structure, point to either next array element for
+       arrayed struct or next struct element if struct is not arrayed;
+
+       When used for block, point to next element in block */
+    gctINT16                        nextSibling;
+
+    /* Only used for structure or blocks;
+       When used for structure, point to either prev array element for
+       arrayed struct or prev struct element if struct is not arrayed;
+
+       When used for block, point to previous element in block */
+    gctINT16                        prevSibling;
+
+    /* used for structure, point to parent _gcUNIFORM
+       or for associated sampler of LOD_MIN_MAX and LEVEL_BASE_SIZE */
+    gctINT16                        parent;
+
+    /* image format */
+    gctINT16                        imageFormat;
+
+    gcUNIFORM                       followingAddr;
+    gctUINT32                       followingOffset;            /* or sampler_t constant value */
+
+    /* Length of the uniform name. */
+    gctINT                          nameLength;
+
+    /* The uniform name. */
+    char                            name[1];
+};
+
+#define GetUniformCategory(u)                   ((u)->_varCategory)
+#define SetUniformCategory(u, c)                ((u)->_varCategory = (c))
+#define GetUniformBlockID(u)                    ((u)->blockIndex)
+#define SetUniformBlockID(u, b)                 ((u)->blockIndex = (b))
+#define GetUniformResOpFlags(u)                 ((u)->resOpFlag)
+#define SetUniformResOpFlags(u, a)              ((u)->resOpFlag = (a))
+#define SetUniformResOpFlag(u, a)               ((u)->resOpFlag |= (a))
+#define GetUniformArrayStride(u)                ((u)->arrayStride)
+#define SetUniformArrayStride(u, a)             ((u)->arrayStride = (a))
+#define GetUniformMatrixStride(u)               ((u)->matrixStride)
+#define SetUniformMatrixStride(u, m)            ((u)->matrixStride = (m))
+#define GetUniformIsRowMajor(u)                 ((u)->isRowMajor)
+#define GetUniformOffset(u)                     ((u)->offset)
+#define GetUniformType(un)                      ((un)->u.type)
+#define GetUniformNumStructureElement(un)       ((un)->u.numStructureElement)
+#define SetUniformNumStructureElement(un, m)    ((un)->u.numStructureElement = (m))
+#define GetUniformNumBlockElement(un)           ((un)->u.numBlockElement)
+#define GetUniformIndex(u)                      ((u)->index)
+#define GetUniformGlUniformIndex(u)             ((u)->glUniformIndex)
+#define SetUniformGlUniformIndex(u, g)          ((u)->glUniformIndex = (g))
+#define GetUniformImageSamplerIndex(u)          ((u)->imageSamplerIndex)
+#define GetUniformPrecision(u)                  ((u)->precision)
+#define GetUniformArraySize(u)                  ((u)->arraySize)
+#define GetUniformUsedArraySize(u)              ((u)->usedArraySize)
+#define SetUniformUsedArraySize(u, v)           (GetUniformUsedArraySize(u) = (v))
+#define GetUniformBinding(u)                    ((u)->binding)
+#define SetUniformBinding(u, b)                 ((u)->binding = (b))
+#define GetUniformOffset(u)                     ((u)->offset)
+#define SetUniformOffset(u, o)                  ((u)->offset = (o))
+#define GetUniformLayoutLocation(u)             ((u)->location)
+#define SetUniformLayoutLocation(u, l)          ((u)->location = (l))
+#define GetUniformModelViewProjection(u)        ((u)->modelViewProjection)
+#define GetUniformFormat(u)                     ((u)->format)
+#define GetUniformVectorSize(u)                 ((u)->vectorSize)
+#define SetUniformVectorSize(u, g)              (GetUniformVectorSize(u) = (g))
+#define GetUniformTypeNameOffset(u)             ((u)->typeNameOffset)
+#define SetUniformTypeNameOffset(u, g)          (GetUniformTypeNameOffset(u) = (g))
+#define GetUniformIsPointer(u)                  ((u)->isPointer)
+#define GetUniformPhysical(u)                   ((u)->physical)
+#define SetUniformPhysical(u, p)                (GetUniformPhysical(u) = (p))
+#define GetUniformSamplerPhysical(u)            ((u)->samplerPhysical)
+#define SetUniformSamplerPhysical(u, p)         (GetUniformSamplerPhysical(u) = (p))
+#define GetUniformSwizzle(u)                    ((u)->swizzle)
+#define SetUniformSwizzle(u, s)                 (GetUniformSwizzle(u) = (s))
+#define GetUniformAddress(u)                    ((u)->address)
+#define GetUniformInitializer(u)                ((u)->initializer)
+#define SetUniformInitializer(u, i)             (GetUniformInitializer(u) = (i))
+#define GetUniformDummyUniformIndex(u)          ((u)->dummyUniformIndex)
+#define setUniformDummyUniformIndex(u, i)       ((u)->dummyUniformIndex = (i))
+#define GetUniformMatchIndex(u)                 ((u)->matchIndex)
+#define GetUniformFirstChild(u)                 ((u)->firstChild)
+#define GetUniformNextSibling(u)                ((u)->nextSibling)
+#define SetUniformNextSibling(u, g)             (GetUniformNextSibling(u) = (g))
+#define GetUniformPrevSibling(u)                ((u)->prevSibling)
+#define SetUniformPrevSibling(u, g)             (GetUniformPrevSibling(u) = (g))
+#define GetUniformParent(u)                     ((u)->parent)
+#define SetUniformParent(u, g)                  ((u)->parent = (g))
+#define GetUniformFollowingAddr(u)              ((u)->followingAddr)
+#define SetUniformFollowingAddr(u, f)           ((u)->followingAddr = (f))
+#define GetUniformFollowingOffset(u)            ((u)->followingOffset)
+#define SetUniformFollowingOffset(u, f)         ((u)->followingOffset = (f))
+#define GetUniformNameLength(u)                 ((u)->nameLength)
+#define GetUniformName(u)                       ((u)->name)
+#define GetUniformImageFormat(u)                ((u)->imageFormat)
+#define SetUniformImageFormat(u, g)             ((u)->imageFormat = (g))
+#define GetUniformQualifier(u)                  ((u)->qualifier)
+#define SetUniformQualifier(u, g)               ((u)->qualifier |= (g))
+#define ClrUniformAddrSpaceQualifier(u)         ((u)->qualifier &= ~gcd_ADDRESS_SPACE_QUALIFIERS)
+#define SetUniformAddrSpaceQualifier(u, g)      ((u)->qualifier = ((u)->qualifier & ~gcd_ADDRESS_SPACE_QUALIFIERS) | (g))
+#define GetUniformShaderKind(u)                 ((u)->shaderKind)
+#define SetUniformShaderKind(u, g)              (GetUniformShaderKind(u) = (g))
+#define GetUniformArrayLengthCount(u)           ((u)->arrayLengthCount)
+#define GetUniformSingleLevelArraySzie(u, l)    ((u)->arrayLengthList[l])
+#define isUniformArraysOfArrays(u)              (GetUniformArrayLengthCount(u) > 1)
+
+/* Same structure, but inside a binary. */
+typedef struct _gcBINARY_UNIFORM
+{
+    union
+    {
+        /* Data type for this most-inner variable. */
+        gctINT16                    type;
+
+        /* Number of element in structure if arraySize of this */
+        /* struct is 1, otherwise, set it to 0 */
+        gctUINT16                   numStructureElement;
+    }
+    u;
+
+    /* Number of array elements for this uniform. */
+    gctINT16                        arraySize;
+
+    gctUINT16                       arrayLengthCount;
+
+    /* Length of the uniform name. */
+    gctINT16                        nameLength;
+
+    /* uniform flags */
+    char                            flags[sizeof(gceUNIFORM_FLAGS)];
+
+    /* Corresponding Index of Program's GLUniform */
+    gctINT16                        glUniformIndex;
+
+    /* Variable category */
+    gctINT16                        varCategory;
+
+    /* Only used for structure, point to either first array element for */
+    /* arrayed struct or first struct element if struct is not arrayed */
+    gctINT16                        firstChild;
+
+    /* Only used for structure, point to either next array element for */
+    /* arrayed struct or next struct element if struct is not arrayed */
+    gctINT16                        nextSibling;
+
+    /* Only used for structure, point to either prev array element for */
+    /* arrayed struct or prev struct element if struct is not arrayed */
+    gctINT16                        prevSibling;
+
+    /* Only used for structure, point to parent _gcUNIFORM */
+    gctINT16                        parent;
+
+    /* precision */
+    gctINT16                        precision;
+
+    /* ES31 explicit location for default block uniforms;  -1 if not specify. */
+    gctINT                          location;
+
+    /* ES31 explicit base address uniform for atomic counter;  -1 if not specify. */
+    gctINT16                        baseBindingIdx;
+
+    /* HALTI extras begin: */
+    /* Uniform block index:
+       Default block index = -1 */
+    gctINT16                        blockIndex;
+
+    /* stride on array or matrix */
+    char                            arrayStride[sizeof(gctINT32)];
+
+    gctINT16                        matrixStride;
+
+    /* memory order of matrices */
+    gctINT16                        isRowMajor;
+
+    /* offset from uniform block's base address */
+    char                            offset[sizeof(gctINT32)];
+
+    /* compile-time constant value */
+    char                            initializer[sizeof(gcsValue)];
+
+    /* Dummy-uniform index for LTC uniform, -1 for non-ltc uniforms. */
+    gctINT16                        dummyUniformIndex;
+
+    /* 3.1 explicit binding for opaque uniforms, -1 if not specify. */
+    char                            binding[sizeof(gctINT32)];
+
+    /* 3.1 image format */
+    gctINT16                        imageFormat;
+
+    /* Number of array elements that are used in the shader. */
+    gctINT16                        usedArraySize;
+
+    /* physical and address. */
+    gctINT16                        physical;
+    gctINT16                        samplerPhysical;
+    char                            address[sizeof(gctUINT32)];
+
+    char                            resOpFlag[sizeof(gctUINT32)];
+
+    /* HALTI extras end: */
+    /* The uniform arrayLengthList and name. */
+    char                            memory[1];
+}
+* gcBINARY_UNIFORM;
+
+/* Same structure, but inside a binary with more variables. */
+typedef struct _gcBINARY_UNIFORM_EX
+{
+    /* Uniform type of type gcUNIFORM_TYPE. */
+    union
+    {
+        /* Data type for this most-inner variable. */
+        gctINT16                    type;
+
+        /* Number of element in structure if arraySize of this */
+        /* struct is 1, otherwise, set it to 0 */
+        gctUINT16                   numStructureElement;
+    }
+    u;
+
+    /* Index of the uniform. */
+    gctUINT16                       index;
+
+    /* Number of array elements for this uniform. */
+    gctINT16                        arraySize;
+
+    gctUINT16                       arrayLengthCount;
+
+    /* Flags. */
+    char                            flags[sizeof(gceUNIFORM_FLAGS)];
+
+    /* Format of element of the uniform shaderType. */
+    gctUINT16                       format;
+
+    /* Wheter the uniform is a pointer. */
+    gctINT16                        isPointer;
+
+    /* precision */
+    gctINT16                        precision;
+
+    /* Length of the uniform name. */
+    gctINT16                        nameLength;
+
+    /* Corresponding Index of Program's GLUniform */
+    gctINT16                        glUniformIndex;
+
+    /* Index to corresponding image sampler */
+    gctUINT16                       imageSamplerIndex;
+
+    /* compile-time constant value */
+    char                            initializer[sizeof(gcsValue)];
+
+    /* Dummy-uniform index for LTC uniform, -1 for non-ltc uniforms. */
+    gctINT16                        dummyUniformIndex;
+
+    /* type qualifier is currently 16bit long.
+       If it ever changes to more than 16bits, the alignment has to be adjusted
+       when writing out to a shader binary
+    */
+    gctTYPE_QUALIFIER               qualifier;
+
+    /* companion to format field to denote vector size,
+       value of 0 denote the underlying type is scalar */
+    gctINT16                        vectorSize;
+
+    /* offset to typeNameBuffer in gcSHADER at which the name of derived type reside */
+    gctCHAR                         typeNameOffset[sizeof(gctINT)];
+
+    /* Variable category */
+    gctINT16                        varCategory;
+
+    /* Only used for structure, point to either first array element for */
+    /* arrayed struct or first struct element if struct is not arrayed */
+    gctINT16                        firstChild;
+
+    /* Only used for structure, point to either next array element for */
+    /* arrayed struct or next struct element if struct is not arrayed */
+    gctINT16                        nextSibling;
+
+    /* Only used for structure, point to either prev array element for */
+    /* arrayed struct or prev struct element if struct is not arrayed */
+    gctINT16                        prevSibling;
+
+    /* Only used for structure, point to parent _gcUNIFORM */
+    gctINT16                        parent;
+
+    /* Uniform block index:
+       Default block index = -1 */
+    gctINT16                        blockIndex;
+
+    /* stride on array */
+    char                            arrayStride[sizeof(gctINT32)];
+
+    /* offset from uniform block's base address */
+    char                            offset[sizeof(gctINT32)];
+
+    /* physical and address. */
+    gctINT16                        physical;
+    gctINT16                        samplerPhysical;
+    char                            address[sizeof(gctUINT32)];
+
+    char                            resOpFlag[sizeof(gctUINT32)];
+
+    /* The uniform arrayLengthList and name. */
+    char                            memory[1];
+}
+* gcBINARY_UNIFORM_EX;
+
+
+typedef enum _gceOUTPUT_Flag
+{
+    gcOUTPUT_CONVERTEDTOPHYSICAL        = 0x01,
+    gcOUTPUT_ALWAYSUSED                 = 0x02,
+    gcOUTPUT_ISNOTUSED                  = 0x04,
+    gcOUTPUT_PACKEDAWAY                 = 0x08,
+
+    /* per-vertex array for TCS/TES */
+    gcOUTPUT_ISPERVERTEXARRAY           = 0x10,
+    /* the output is per-patch output */
+    gcOUTPUT_ISPERPATCH                 = 0x20,
+    gcOUTPUT_ISARRAY                    = 0x40,
+    gcOUTPUT_ISPOSITION                 = 0x80,
+    gcOUTPUT_ENABLED                    = 0x100,
+    gcOUTPUT_ISINVARIANT                = 0x200,
+    gcOUTPUT_ISPRECISE                  = 0x400,
+    gcOUTPUT_ISIOBLOCKMEMBER            = 0x800,
+    gcOUTPUT_ISINSTANCEMEMBER           = 0x1000,
+    gcOUTPUT_ISCENTROID                 = 0x2000,
+    gcOUTPUT_ISSAMPLE                   = 0x4000,
+    gcOUTPUT_ISPERVERTEXNOTARRAY        = 0x8000,
+    gcOUTPUT_STATICALLYUSED             = 0x10000,
+} gceOUTPUT_Flag;
+
+#define gcmOUTPUT_convertedToPhysical(out)  (((out)->flags_ & gcOUTPUT_CONVERTEDTOPHYSICAL) != 0)
+#define gcmOUTPUT_packedAway(out)           (((out)->flags_ & gcOUTPUT_PACKEDAWAY) != 0)
+#define gcmOUTPUT_alwaysUsed(out)           (((out)->flags_ & gcOUTPUT_ALWAYSUSED) != 0)
+#define gcmOUTPUT_isNotUsed(out)            (((out)->flags_ & gcOUTPUT_ISNOTUSED) != 0)
+#define gcmOUTPUT_isPerPatch(out)           (((out)->flags_ & gcOUTPUT_ISPERPATCH) != 0)
+#define gcmOUTPUT_isPerVertexArray(out)     (((out)->flags_ & gcOUTPUT_ISPERVERTEXARRAY) != 0)
+#define gcmOUTPUT_isPerVertexNotArray(out)  (((out)->flags_ & gcOUTPUT_ISPERVERTEXNOTARRAY) != 0)
+#define gcmOUTPUT_isArray(out)              (((out)->flags_ & gcOUTPUT_ISARRAY) != 0)
+#define gcmOUTPUT_isPosition(out)           (((out)->flags_ & gcOUTPUT_ISPOSITION) != 0)
+#define gcmOUTPUT_enabled(out)              (((out)->flags_ & gcOUTPUT_ENABLED) != 0)
+#define gcmOUTPUT_isInvariant(out)          (((out)->flags_ & gcOUTPUT_ISINVARIANT) != 0)
+#define gcmOUTPUT_isPrecise(out)            (((out)->flags_ & gcOUTPUT_ISPRECISE) != 0)
+#define gcmOUTPUT_isIOBLockMember(out)      (((out)->flags_ & gcOUTPUT_ISIOBLOCKMEMBER) != 0)
+#define gcmOUTPUT_isInstanceMember(out)     (((out)->flags_ & gcOUTPUT_ISINSTANCEMEMBER) != 0)
+#define gcmOUTPUT_isCentroid(out)           (((out)->flags_ & gcOUTPUT_ISCENTROID) != 0)
+#define gcmOUTPUT_isSample(out)             (((out)->flags_ & gcOUTPUT_ISSAMPLE) != 0)
+#define gcmOUTPUT_isStaticallyUsed(out)     (((out)->flags_ & gcOUTPUT_STATICALLYUSED) != 0)
+
+#define gcmOUTPUT_SetConvertedToPhysicaly(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_CONVERTEDTOPHYSICAL) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_CONVERTEDTOPHYSICAL))
+
+#define gcmOUTPUT_SetPackedAway(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_PACKEDAWAY) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_PACKEDAWAY))
+
+#define gcmOUTPUT_SetAlwaysUsed(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ALWAYSUSED) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ALWAYSUSED))
+
+#define gcmOUTPUT_SetNotUsed(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISNOTUSED) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISNOTUSED))
+
+#define gcmOUTPUT_SetIsPerPatch(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISPERPATCH) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISPERPATCH))
+
+#define gcmOUTPUT_SetIsPerVertexArray(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISPERVERTEXARRAY) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISPERVERTEXARRAY))
+
+#define gcmOUTPUT_SetIsPerVertexNotArray(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISPERVERTEXNOTARRAY) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISPERVERTEXNOTARRAY))
+
+#define gcmOUTPUT_SetIsArray(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISARRAY) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISARRAY))
+
+#define gcmOUTPUT_SetIsPosition(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISPOSITION) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISPOSITION))
+
+#define gcmOUTPUT_SetEnabled(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ENABLED) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ENABLED))
+
+#define gcmOUTPUT_SetIsInvariant(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISINVARIANT) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISINVARIANT))
+
+#define gcmOUTPUT_SetIsPrecise(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISPRECISE) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISPRECISE))
+
+#define gcmOUTPUT_SetIsIOBlockMember(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISIOBLOCKMEMBER) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISIOBLOCKMEMBER))
+
+#define gcmOUTPUT_SetIsInstanceMember(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISINSTANCEMEMBER) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISINSTANCEMEMBER))
+
+#define gcmOUTPUT_SetIsCentroid(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISCENTROID) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISCENTROID))
+
+#define gcmOUTPUT_SetIsSample(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_ISSAMPLE) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_ISSAMPLE))
+
+#define gcmOUTPUT_SetIsStaticallyUsed(out,v )  \
+        ((out)->flags_ = ((out)->flags_ & ~gcOUTPUT_STATICALLYUSED) | \
+                          ((v) == gcvFALSE ? 0 : gcOUTPUT_STATICALLYUSED))
+
+/* Structure that defines an output for a shader. */
+struct _gcOUTPUT
+{
+    /* The object. */
+    gcsOBJECT                       object;
+
+    /* Index of the output. */
+    gctUINT16                       index;
+
+    /* Original type for this output, driver should use this for transform feedback. */
+    gcSHADER_TYPE                   origType;
+
+    /* Type for this output, this type may be changed after varying packing. */
+    gcSHADER_TYPE                   type;
+
+    /* Precision of the uniform. */
+    gcSHADER_PRECISION              precision;
+
+    /* Temporary register index that holds the output value. */
+    gctUINT32                       tempIndex;
+
+    gctUINT32                       flags_;
+
+    /* Number of array elements for this output. */
+    gctINT                          arraySize;
+
+    /* array Index for the output */
+    gctINT                          arrayIndex;
+
+    /* Flat output or smooth output. */
+    gcSHADER_SHADERMODE             shaderMode;
+
+    /* Location index. */
+    gctINT                          location;
+    gctINT                          output2RTIndex; /* user may specify location 1,3,
+                                                     * real RT index are 1->0, 3->1 */
+
+    /* Field Index. */
+    gctINT                          fieldIndex;
+
+    /* IO block index. */
+    gctINT                          ioBlockIndex;
+
+    /* IO block array index. */
+    gctINT                          ioBlockArrayIndex;
+
+    /* Only used for a IO block member, point to the next element in block. */
+    gctINT16                        nextSibling;
+
+    /* Only used for a IO block member, point to the previous element in block. */
+    gctINT16                        prevSibling;
+
+    /* The variable index of the type name, it is only enabled for a structure member only. */
+    gctINT16                        typeNameVarIndex;
+
+    /* layout qualifier */
+    gceLAYOUT_QUALIFIER             layoutQualifier;
+
+    /* Length of the output name. */
+    gctINT                          nameLength;
+
+    /* The output name. */
+    char                            name[1];
+};
+
+#define GetOutputObject(o)                  (&(o)->object)
+#define GetOutputIndex(o)                   ((o)->index)
+#define GetOutputOrigType(o)                ((o)->origType)
+#define GetOutputType(o)                    ((o)->type)
+#define GetOutputPrecision(o)               ((o)->precision)
+#define GetOutputArraySize(o)               ((o)->arraySize)
+#define GetOutputArrayIndex(o)              ((o)->arrayIndex)
+#define GetOutputTempIndex(o)               ((o)->tempIndex)
+#define GetOutputShaderMode(o)              ((o)->shaderMode)
+#define GetOutputLocation(o)                ((o)->location)
+#define GetOutput2RTIndex(o)                ((o)->output2RTIndex)
+#define GetOutputFieldIndex(o)              ((o)->fieldIndex)
+#define GetOutputNameLength(o)              ((o)->nameLength)
+#define GetOutputName(o)                    ((o)->name)
+#define GetOutputIOBlockIndex(o)            ((o)->ioBlockIndex)
+#define SetOutputIOBlockIndex(o, i)         (GetOutputIOBlockIndex(o) = (i))
+#define GetOutputIOBlockArrayIndex(o)       ((o)->ioBlockArrayIndex)
+#define SetOutputIOBlockArrayIndex(o, i)    (GetOutputIOBlockArrayIndex(o) = (i))
+#define GetOutputNextSibling(o)             ((o)->nextSibling)
+#define SetOutputNextSibling(o, i)          (GetOutputNextSibling(o) = (i))
+#define GetOutputPrevSibling(o)             ((o)->prevSibling)
+#define SetOutputPrevSibling(o, i)          (GetOutputPrevSibling(o) = (i))
+#define GetOutputTypeNameVarIndex(o)        ((o)->typeNameVarIndex)
+#define SetOutputTypeNameVarIndex(o, i)     (GetOutputTypeNameVarIndex(o) = (i))
+
+/* Same structure, but inside a binary. */
+typedef struct _gcBINARY_OUTPUT
+{
+    /* Index of the output. */
+    gctUINT16                       index;
+
+    /* Original type for this output, driver should use this for transform feedback. */
+    gctINT16                        origType;
+
+    /* Type for this output. */
+    gctINT16                        type;
+
+    /* Number of array elements for this output. */
+    gctINT16                        arraySize;
+
+    /* Temporary register index that holds the output value. */
+    gctUINT32                       tempIndex;
+
+    gctUINT16                       flags1;
+
+    gctUINT16                       flags2;
+
+    /* Length of the output name. */
+    gctINT16                        nameLength;
+
+    /* precision */
+    gctINT16                        precision;
+
+    /* IO block index. */
+    gctINT16                        ioBlockIndex;
+
+    /* IO block array index. */
+    gctINT16                        ioBlockArrayIndex;
+
+    /* Only used for a IO block member, point to the next element in block. */
+    gctINT16                        nextSibling;
+
+    /* Only used for a IO block member, point to the previous element in block. */
+    gctINT16                        prevSibling;
+
+    /* The variable index of the type name, it is only enabled for a structure member only. */
+    gctINT16                        typeNameVarIndex;
+
+    /* shader mode: flat/smooth/... */
+    gctINT16                        shaderMode;
+
+    /* layout qualifier */
+    char                            layoutQualifier[sizeof(gceLAYOUT_QUALIFIER)];
+
+    /* The output name. */
+    char                            name[1];
+}
+* gcBINARY_OUTPUT;
+
+/* NOTE - size of gceVARIABLE_FLAG enum is gctUINT16
+   If it goes beyond gctUINT16, flags field in gcBINARY_UNIFORM needs to be adjusted
+   and gcSHADER_Load* to be updated accordingly
+*/
+typedef enum _gceVARIABLE_FLAG
+{
+    gceVARFLAG_NONE                     = 0x00,
+    gceVARFLAG_IS_LOCAL                 = 0x01,
+    gceVARFLAG_IS_OUTPUT                = 0x02,
+    gceVARFLAG_IS_INPUT                 = 0x04,
+    gceVARFLAG_IS_ROW_MAJOR             = 0x08,
+    gceVARFLAG_IS_COMPILER_GENERATED    = 0x10,
+    gceVARFLAG_IS_NOT_USED              = 0x20,
+    gceVARFLAG_IS_STATIC                = 0x40,
+    gceVARFLAG_IS_EXTERN                = 0x80,
+    gceVARFLAG_IS_POINTER               = 0x100,
+    gceVARFLAG_IS_PRECISE               = 0x200,
+    gceVARFLAG_IS_STATICALLY_USED       = 0x400,
+    gceVARFLAG_IS_PERVERTEX             = 0x800,
+    gceVARFLAG_IS_HOST_ENDIAN           = 0x1000,
+    /* This variable is a function parameter, but the function is deleted. */
+    gceVARFLAG_IS_PARAM_FUNC_DELETE     = 0x2000,
+    gceVARFLAG_IS_EXTENDED_VECTOR       = 0x4000,
+} gceVARIABLE_FLAG;
+
+/* Structure that defines a variable for a shader. */
+struct _gcVARIABLE
+{
+    /* The object. */
+    gcsOBJECT                       object;
+
+    /* Index of the variable. */
+    gctUINT16                       index;
+    /* If a storage block member is used on both VS and PS,
+    ** the index of this variable on the other shader would be saved by this.
+    */
+    gctINT16                        matchIndex;
+
+    /* Storage block index: Default block index = gcvBLOCK_INDEX_DEFAULT */
+    gctINT16                        blockIndex;
+
+    /* Variable category */
+    gcSHADER_VAR_CATEGORY           _varCategory;
+
+    /* Only used for structure, point to either first array element for */
+    /* arrayed struct or first struct element if struct is not arrayed */
+    gctINT16                        firstChild;
+
+    /* Only used for structure, point to either next array element for */
+    /* arrayed struct or next struct element if struct is not arrayed */
+    gctINT16                        nextSibling;
+
+    /* Only used for structure, point to either prev array element for */
+    /* arrayed struct or prev struct element if struct is not arrayed */
+    gctINT16                        prevSibling;
+
+    /* Only used for structure, point to parent _gcVARIABLE */
+    gctINT16                        parent;
+
+    union
+    {
+        /* Data type for this most-inner variable. */
+        gcSHADER_TYPE               type;
+
+        /* Number of element in structure if arraySize of this */
+        /* struct is 1, otherwise, set it to 0 */
+        gctUINT16                   numStructureElement;
+
+        /* Number of elements in block */
+        gctUINT16                   numBlockElement;
+    }
+    u;
+
+    /* type qualifier */
+    gctTYPE_QUALIFIER               qualifier;
+
+    /* Precision of the uniform. */
+    gcSHADER_PRECISION              precision;
+
+    gceVARIABLE_FLAG                flags;
+
+    /* Number of array elements for this variable, at least 1 */
+    gctINT                          arraySize;
+
+    /* Number of array level. */
+    gctINT                          arrayLengthCount;
+
+    /* Array size for every array level. */
+    gctINT *                        arrayLengthList;
+
+    /* Start temporary register index that holds the variable value. */
+    gctUINT32                       tempIndex;
+
+    /* stride on array or matrix */
+    gctINT32                        arrayStride;
+    gctINT16                        matrixStride;
+
+    /* Top level array data associated with this variable */
+    gctINT                          topLevelArraySize;
+    gctINT32                        topLevelArrayStride;
+
+    /* offset from storage block's base address */
+    gctINT32                        offset;
+
+    /* Length of the variable name. */
+    gctINT                          nameLength;
+
+    /* The variable name. */
+    char                            name[1];
+};
+
+#define GetVariableObject(v)                    (&(v)->object)
+#define GetVariableIndex(v)                     ((v)->index)
+#define GetVariableCategory(v)                  ((v)->_varCategory)
+#define SetVariableCategory(v, c)               ((v)->_varCategory = (c))
+#define GetVariableBlockID(v)                   ((v)->blockIndex)
+#define GetVariableArrayStride(v)               ((v)->arrayStride)
+#define SetVariableArrayStride(v, s)            ((v)->arrayStride = (s))
+#define GetVariableTopLevelArrayStride(v)       ((v)->topLevelArrayStride)
+#define SetVariableTopLevelArrayStride(v, s)    ((v)->topLevelArrayStride = (s))
+#define GetVariableMatrixStride(v)              ((v)->matrixStride)
+#define GetVariableOffset(v)                    ((v)->offset)
+#define SetVariableOffset(v, s)                 ((v)->offset = (s))
+#define GetVariableFirstChild(v)                ((v)->firstChild)
+#define GetVariableNextSibling(v)               ((v)->nextSibling)
+#define GetVariablePrevSibling(v)               ((v)->prevSibling)
+#define GetVariableParent(v)                    ((v)->parent)
+#define GetVariableType(v)                      ((v)->u.type)
+#define SetVariableType(v, t)                   (GetVariableType(v) = (t))
+#define GetVariableNumStructureElement(v)       ((v)->u.numStructureElement)
+#define GetVariableNumBlockElement(v)           ((v)->u.numBlockElement)
+#define GetVariableQualifier(v)                 ((v)->qualifier)
+#define SetVariableQualifier(v, s)              ((v)->qualifier |= (s))
+#define GetVariablePrecision(v)                 ((v)->precision)
+#define GetVariableFlags(v)                     ((v)->flags)
+#define GetVariableIsLocal(v)                   (((v)->flags & gceVARFLAG_IS_LOCAL) != 0)
+#define GetVariableIsOtput(v)                   (((v)->flags & gceVARFLAG_IS_OUTPUT) != 0)
+#define GetVariableIsRowMajor(v)                (((v)->flags & gceVARFLAG_IS_ROW_MAJOR) != 0)
+#define GetVariableIsCompilerGenerated(v)       (((v)->flags & gceVARFLAG_IS_COMPILER_GENERATED) != 0)
+#define GetVariableIsPointer(v)                 (((v)->flags & gceVARFLAG_IS_POINTER) != 0)
+#define GetVariableIsPrecise(v)                 (((v)->flags & gceVARFLAG_IS_PRECISE) != 0)
+#define GetVariableIsPerVertex(v)               (((v)->flags & gceVARFLAG_IS_PERVERTEX) != 0)
+#define GetVariableIsHostEndian(v)              (((v)->flags & gceVARFLAG_IS_HOST_ENDIAN) != 0)
+#define GetVariableIsParamFuncDelete(v)         (((v)->flags & gceVARFLAG_IS_PARAM_FUNC_DELETE) != 0)
+#define GetVariableIsExtendedVector(v)          (((v)->flags & gceVARFLAG_IS_EXTENDED_VECTOR) != 0)
+
+#define GetVariableArraySize(v)                 ((v)->arraySize)
+#define SetVariableArraySize(v, s)              ((v)->arraySize = (s))
+#define GetVariableTopLevelArraySize(v)         ((v)->topLevelArraySize)
+#define SetVariableTopLevelArraySize(v, s)      ((v)->topLevelArraySize = (s))
+#define GetVariableArrayLengthCount(v)          ((v)->arrayLengthCount)
+#define GetVariableTempIndex(v)                 ((v)->tempIndex)
+#define GetVariableNameLength(v)                ((v)->nameLength)
+#define GetVariableName(v)                      ((v)->name)
+
+#define GetVariableKnownArraySize(v)            ((v)->arraySize > 0 ? (v)->arraySize : 1)
+
+#define isVariableArray(v)                      ((v)->arrayLengthCount > 0 || (v)->arraySize == -1)
+#define isVariableArraysOfArrays(v)             (GetVariableArrayLengthCount(v) > 1)
+#define isVariableFunctionArg(v)                ((v)->_varCategory >= gcSHADER_VAR_CATEGORY_FUNCTION_INPUT_ARGUMENT && (v)->_varCategory <= gcSHADER_VAR_CATEGORY_FUNCTION_INOUT_ARGUMENT)
+#define isVariableNormal(v)                     (((v)->_varCategory == gcSHADER_VAR_CATEGORY_NORMAL) || (isVariableFunctionArg(v)))
+#define isVariableTopLevelStruct(v)             ((v)->_varCategory == gcSHADER_VAR_CATEGORY_TOP_LEVEL_STRUCT)
+#define isVariableStruct(v)                     (isVariableTopLevelStruct(v) || ((v)->_varCategory == gcSHADER_VAR_CATEGORY_STRUCT))
+#define isVariableBlockMember(v)                ((v)->_varCategory == gcSHADER_VAR_CATEGORY_BLOCK_MEMBER)
+#define isVariableInactive(v)                   (gcvFALSE)
+#define isVariableSimple(v)                     (isVariableNormal(v) || isVariableBlockMember(v) )
+#define isVariableStructMember(v)               (GetVariableParent(v) != -1)
+#define isVariableTypeName(v)                   (GetVariableCategory(v) == gcSHADER_VAR_CATEGORY_TYPE_NAME)
+
+#define SetVariableFlag(v, f)                   do { (v)->flags |= f; } while(0)
+#define SetVariableFlags(v, f)                  do { (v)->flags = f; } while(0)
+#define SetVariableIsLocal(v)                   do { (v)->flags |= gceVARFLAG_IS_LOCAL; } while(0)
+#define SetVariableIsOutput(v)                  do { (v)->flags |= gceVARFLAG_IS_OUTPUT; } while(0)
+#define SetVariableIsRowMajor(v)                do { (v)->flags |= gceVARFLAG_IS_ROW_MAJOR; } while(0)
+#define SetVariableIsCompilerGenerated(v)       do { (v)->flags |= gceVARFLAG_IS_COMPILER_GENERATED; } while(0)
+#define SetVariableIsNotUsed(v)                 do { (v)->flags |= gceVARFLAG_IS_NOT_USED; } while(0)
+#define SetVariableIsPointer(v)                 do { (v)->flags |= gceVARFLAG_IS_POINTER; } while(0)
+#define SetVariableIsExtern(v)                  do { (v)->flags |= gceVARFLAG_IS_EXTERN; } while(0)
+#define SetVariableIsStatic(v)                  do { (v)->flags |= gceVARFLAG_IS_STATIC; } while(0)
+#define SetVariableIsPrecise(v)                 do { (v)->flags |= gceVARFLAG_IS_PRECISE; } while(0)
+#define SetVariableIsPerVertex(v)               do { (v)->flags |= gceVARFLAG_IS_PERVERTEX; } while(0)
+#define SetVariableIsHostEndian(v)              do { (v)->flags |= gceVARFLAG_IS_HOST_ENDIAN; } while(0)
+#define SetVariableIsStaticallyUsed(v)          do { (v)->flags |= gceVARFLAG_IS_STATICALLY_USED; } while(0)
+#define SetVariableIsParamFuncDelete(v)         do { (v)->flags |= gceVARFLAG_IS_PARAM_FUNC_DELETE; } while(0)
+
+#define IsVariableIsNotUsed(v)                  (((v)->flags & gceVARFLAG_IS_NOT_USED) != 0)
+#define IsVariablePointer(v)                    (((v)->flags & gceVARFLAG_IS_POINTER) != 0)
+#define IsVariableExtern(v)                     (((v)->flags & gceVARFLAG_IS_EXTERN) != 0)
+#define IsVariableStatic(v)                     (((v)->flags & gceVARFLAG_IS_STATIC) != 0)
+#define IsVariableLocal(v)                      (((v)->flags & gceVARFLAG_IS_LOCAL) != 0)
+#define IsVariableGlobal(v)                     (((v)->flags & (gceVARFLAG_IS_STATIC | gceVARFLAG_IS_LOCAL)) == 0)
+#define IsVariableOutput(v)                     (((v)->flags & gceVARFLAG_IS_OUTPUT) != 0)
+#define IsVariablePrecise(v)                    (((v)->flags & gceVARFLAG_IS_PRECISE) != 0)
+#define IsVariableHostEndian(v)                 (((v)->flags & gceVARFLAG_IS_HOST_ENDIAN) != 0)
+#define IsVariableStaticallyUsed(v)             (((v)->flags & gceVARFLAG_IS_STATICALLY_USED) != 0)
+
+/* Same structure, but inside a binary. */
+typedef struct _gcBINARY_VARIABLE
+{
+    union
+    {
+        /* Data type for this most-inner variable. */
+        gctUINT16                     type;
+
+        /* Number of element in structure if arraySize of this */
+        /* struct is 1, otherwise, set it to 0 */
+        gctUINT16                    numStructureElement;
+    }
+    u;
+
+    /* Number of array elements for this variable, at least 1,
+           8 bit wide arraySize is not enough and does not match
+           definition in struct _gcVARIABLE. This is a potential
+           problem - KLC
+        */
+    gctINT16                         arraySize;
+
+    gctUINT16                       arrayLengthCount;
+
+    /* Start temporary register index that holds the variable value. */
+    gctUINT32                       tempIndex;
+
+    /* Length of the variable name. */
+    gctINT16                        nameLength;
+
+    /* Variable category */
+    gctINT16                        varCategory;
+
+    /* Only used for structure, point to either first array element for */
+    /* arrayed struct or first struct element if struct is not arrayed */
+    gctINT16                        firstChild;
+
+    /* Only used for structure, point to either next array element for */
+    /* arrayed struct or next struct element if struct is not arrayed */
+    gctINT16                        nextSibling;
+
+    /* Only used for structure, point to either prev array element for */
+    /* arrayed struct or prev struct element if struct is not arrayed */
+    gctINT16                        prevSibling;
+
+    /* Only used for structure, point to parent _gcVARIABLE */
+    gctINT16                        parent;
+
+    /* type qualifier is currently 16bit long.
+       If it ever changes to more than 16bits, the alignment has to be adjusted
+       when writing out to a shader binary
+    */
+    gctTYPE_QUALIFIER               qualifier;
+
+    /* precision */
+    gctINT16                        precision;
+
+    /* flags */
+    gctINT16                        flags;
+
+    /* Storage block index: Default block index = -1 */
+    gctINT16                        blockIndex;
+
+    /* The variable arrayLengthList and name. */
+    char                            memory[1];
+}
+* gcBINARY_VARIABLE;
+
+/* Same structure, but inside a binary. */
+typedef struct _gcBINARY_VARIABLE_EX
+{
+    union
+    {
+        /* Data type for this most-inner variable. */
+        gctUINT16                     type;
+
+        /* Number of element in structure if arraySize of this */
+        /* struct is 1, otherwise, set it to 0 */
+        gctUINT16                    numStructureElement;
+    }
+    u;
+
+    /* Number of array elements for this variable, at least 1,
+           8 bit wide arraySize is not enough and does not match
+           definition in struct _gcVARIABLE. This is a potential
+           problem - KLC
+        */
+    gctINT16                         arraySize;
+
+    gctUINT16                       arrayLengthCount;
+
+    /* Start temporary register index that holds the variable value. */
+    gctUINT32                       tempIndex;
+
+    /* Length of the variable name. */
+    gctINT16                        nameLength;
+
+    /* Variable category */
+    gctINT16                        varCategory;
+
+    /* Only used for structure, point to either first array element for */
+    /* arrayed struct or first struct element if struct is not arrayed */
+    gctINT16                        firstChild;
+
+    /* Only used for structure, point to either next array element for */
+    /* arrayed struct or next struct element if struct is not arrayed */
+    gctINT16                        nextSibling;
+
+    /* Only used for structure, point to either prev array element for */
+    /* arrayed struct or prev struct element if struct is not arrayed */
+    gctINT16                        prevSibling;
+
+    /* Only used for structure, point to parent _gcVARIABLE */
+    gctINT16                        parent;
+
+    /* type qualifier is currently 16bit long.
+       If it ever changes to more than 16bits, the alignment has to be adjusted
+       when writing out to a shader binary
+    */
+    gctTYPE_QUALIFIER               qualifier;
+
+    /* precision */
+    gctINT16                        precision;
+
+    /* flags */
+    gctINT16                        flags;
+
+    /* Storage block index: Default block index = -1 */
+    gctINT16                        blockIndex;
+
+    /* stride on array. For scalar, it represents its size in bytes */
+    char                            arrayStride[sizeof(gctINT32)];
+
+    /* offset from constant memory base address */
+    char                            offset[sizeof(gctINT32)];
+
+    /* The variable arrayLengthList and name. */
+    char                            memory[1];
+}
+* gcBINARY_VARIABLE_EX;
+
+typedef enum _gceFUNCTION_ARGUMENT_FLAG
+{
+    gceFUNCTION_ARGUMENT_FLAG_NONE          = 0x00,
+    gceFUNCTION_ARGUMENT_FLAG_IS_PRECISE    = 0x01,
+} gceFUNCTION_ARGUMENT_FLAG;
+
+typedef struct _gcsFUNCTION_ARGUMENT
+{
+    gctUINT32                       index;
+    gctUINT8                        enable;
+    gctUINT8                        qualifier;
+    gctUINT8                        precision;
+    gctUINT16                       variableIndex;
+    gctUINT8                        flags;
+}
+gcsFUNCTION_ARGUMENT,
+* gcsFUNCTION_ARGUMENT_PTR;
+
+#define GetFuncArgIndex(f)                  ((f)->index)
+#define GetFuncArgEnable(f)                 ((f)->enable)
+#define GetFuncArgQualifier(f)              ((f)->qualifier)
+
+/* Same structure, but inside a binary. */
+typedef struct _gcBINARY_ARGUMENT
+{
+    gctUINT32                       index;
+    gctUINT8                        enable;
+    gctUINT8                        qualifier;
+    gctUINT8                        precision;
+    gctUINT8                        flags;
+    gctUINT16                       variableIndex;
+}
+* gcBINARY_ARGUMENT;
+
+typedef enum _gceFUNCTION_FLAG
+{
+  gcvFUNC_NOATTR                = 0x00,
+  gcvFUNC_INTRINSICS            = 0x01, /* Function is openCL/OpenGL builtin function */
+  gcvFUNC_ALWAYSINLINE          = 0x02, /* Always inline */
+  gcvFUNC_NOINLINE              = 0x04, /* Neve inline */
+  gcvFUNC_INLINEHINT            = 0x08, /* Inline is desirable */
+
+  gcvFUNC_READNONE              = 0x10, /* Function does not access memory */
+  gcvFUNC_READONLY              = 0x20, /* Function only reads from memory */
+  gcvFUNC_STRUCTRET             = 0x40, /* Hidden pointer to structure to return */
+  gcvFUNC_NORETURN              = 0x80, /* Function is not returning */
+
+  gcvFUNC_INREG                 = 0x100, /* Force argument to be passed in register */
+  gcvFUNC_BYVAL                 = 0x200, /* Pass structure by value */
+
+  gcvFUNC_STATIC                = 0x400, /* OPENCL static function */
+  gcvFUNC_EXTERN                = 0x800, /* OPENCL extern function with no body */
+
+  gcvFUNC_NAME_MANGLED          = 0x1000, /* name mangled */
+
+  gcvFUNC_RECOMPILER            = 0x2000, /* A recompile function. */
+  gcvFUNC_RECOMPILER_STUB       = 0x4000, /* The function to stub a recompile function. */
+  gcvFUNC_HAS_SAMPLER_INDEXINED = 0x8000, /* This function has sampler indexing used. */
+  gcvFUNC_PARAM_AS_IMG_SOURCE0  = 0x10000, /* Use parameter as source0 of a IMG op. */
+  gcvFUNC_USING_SAMPLER_VIRTUAL = 0x20000, /* Use sampler virtual instructions, like get_sampler_lmm or get_sampler_lbs. */
+  gcvFUNC_HAS_TEMPREG_BIGGAP    = 0x40000, /* the function has big gap in temp ergister due to called be inlined first */
+  gcvFUNC_NOT_USED              = 0x80000, /* the function is not used the sahder, do not convert to VIR */
+} gceFUNCTION_FLAG;
+
+typedef enum _gceINTRINSICS_KIND
+{
+    gceINTRIN_NONE         = 0, /* not an intrinsics */
+    gceINTRIN_UNKNOWN      = 1, /* is an intrinsics, but unknown kind */
+
+    /* common functions */
+    gceINTRIN_clamp,
+    gceINTRIN_min,
+    gceINTRIN_max,
+    gceINTRIN_sign,
+    gceINTRIN_fmix,
+    gceINTRIN_mix,
+    /* Angle and Trigonometry Functions */
+    gceINTRIN_radians,
+    gceINTRIN_degrees,
+    gceINTRIN_step,
+    gceINTRIN_smoothstep,
+    /* Geometric Functions */
+    gceINTRIN_cross,
+    gceINTRIN_fast_length,
+    gceINTRIN_length,
+    gceINTRIN_distance,
+    gceINTRIN_dot,
+    gceINTRIN_normalize,
+    gceINTRIN_fast_normalize,
+    gceINTRIN_faceforward,
+    gceINTRIN_reflect,
+    gceINTRIN_refract,
+    /* Vector Relational Functions */
+    gceINTRIN_isequal,
+    gceINTRIN_isnotequal,
+    gceINTRIN_isgreater,
+    gceINTRIN_isgreaterequal,
+    gceINTRIN_isless,
+    gceINTRIN_islessequal,
+    gceINTRIN_islessgreater,
+    gceINTRIN_isordered,
+    gceINTRIN_isunordered,
+    gceINTRIN_isfinite,
+    gceINTRIN_isnan,
+    gceINTRIN_isinf,
+    gceINTRIN_isnormal,
+    gceINTRIN_signbit,
+    gceINTRIN_lgamma,
+    gceINTRIN_lgamma_r,
+    gceINTRIN_shuffle,
+    gceINTRIN_shuffle2,
+    gceINTRIN_select,
+    gceINTRIN_bitselect,
+    gceINTRIN_any,
+    gceINTRIN_all,
+    /* Matrix Functions */
+    gceINTRIN_matrixCompMult,
+    /* Async copy and prefetch */
+    gceINTRIN_async_work_group_copy,
+    gceINTRIN_async_work_group_strided_copy,
+    gceINTRIN_wait_group_events,
+    gceINTRIN_prefetch,
+    /* Atomic Functions */
+    gceINTRIN_atomic_add,
+    gceINTRIN_atomic_sub,
+    gceINTRIN_atomic_inc,
+    gceINTRIN_atomic_dec,
+    gceINTRIN_atomic_xchg,
+    gceINTRIN_atomic_cmpxchg,
+    gceINTRIN_atomic_min,
+    gceINTRIN_atomic_max,
+    gceINTRIN_atomic_or,
+    gceINTRIN_atomic_and,
+    gceINTRIN_atomic_xor,
+
+    /* work-item functions */
+    gceINTRIN_get_global_id,
+    gceINTRIN_get_local_id,
+    gceINTRIN_get_group_id,
+    gceINTRIN_get_work_dim,
+    gceINTRIN_get_global_size,
+    gceINTRIN_get_local_size,
+    gceINTRIN_get_global_offset,
+    gceINTRIN_get_num_groups,
+    /* synchronization functions */
+    gceINTRIN_barrier,
+    /* intrinsic builtin functions that are written in source,
+       which needs compile/link to the shader */
+    gceINTRIN_source,
+    gceINTRIN_create_size_for_sampler,
+    gceINTRIN_texture_gather,
+    gceINTRIN_texture_gather_2DRect,
+    gceINTRIN_texture_gather_offset,
+    gceINTRIN_texture_gather_offset_2DRect,
+    gceINTRIN_texture_gather_offsets,
+    gceINTRIN_texture_gather_offsets_2DRect,
+    gceINTRIN_texelFetch_for_MSAA,
+    gceINTRIN_image_size,
+    gceINTRIN_image_load,
+    gceINTRIN_image_store,
+    gceINTRIN_image_atomic,
+    gceINTRIN_MS_interpolate_at_centroid,
+    gceINTRIN_MS_interpolate_at_sample,
+    gceINTRIN_MS_interpolate_at_offset,
+
+} gceINTRINSICS_KIND;
+
+#define IsIntrinsicsKindCreateSamplerSize(Kind)        ((Kind) == gceINTRIN_create_size_for_sampler)
+#define IsIntrinsicsKindTextureGather(Kind)            ((Kind) == gceINTRIN_texture_gather)
+#define IsIntrinsicsKindTextureGather2DRect(Kind)      ((Kind) == gceINTRIN_texture_gather_2DRect)
+#define IsIntrinsicsKindTextureGatherOffset(Kind)      ((Kind) == gceINTRIN_texture_gather_offset)
+#define IsIntrinsicsKindTextureGatherOffset2DRect(Kind)      ((Kind) == gceINTRIN_texture_gather_offset_2DRect)
+#define IsIntrinsicsKindTextureGatherOffsets(Kind)     ((Kind) == gceINTRIN_texture_gather_offsets)
+#define IsIntrinsicsKindTextureGatherOffsets2DRect(Kind)     ((Kind) == gceINTRIN_texture_gather_offsets_2DRect)
+#define IsIntrinsicsKindTexelFetchForMSAA(Kind)        ((Kind) == gceINTRIN_texelFetch_for_MSAA)
+#define IsIntrinsicsKindImageSize(Kind)                ((Kind) == gceINTRIN_image_size)
+#define IsIntrinsicsKindImageLoad(Kind)                ((Kind) == gceINTRIN_image_load)
+#define IsIntrinsicsKindImageStore(Kind)               ((Kind) == gceINTRIN_image_store)
+#define IsIntrinsicsKindImageAtomic(Kind)              ((Kind) == gceINTRIN_image_atomic)
+#define IsIntrinsicsKindInterpolateAtCentroid(Kind)    ((Kind) == gceINTRIN_MS_interpolate_at_centroid)
+#define IsIntrinsicsKindInterpolateAtSample(Kind)      ((Kind) == gceINTRIN_MS_interpolate_at_sample)
+#define IsIntrinsicsKindInterpolateAtOffset(Kind)      ((Kind) == gceINTRIN_MS_interpolate_at_offset)
+#define IsIntrinsicsKindMSInterpolation(Kind)          ((IsIntrinsicsKindInterpolateAtCentroid(Kind)) ||\
+                                                        (IsIntrinsicsKindInterpolateAtSample(Kind)) ||\
+                                                        (IsIntrinsicsKindInterpolateAtOffset(Kind)))
+
+#define IsIntrinsicsKindNeedTexSizeOnly(Kind)          ((IsIntrinsicsKindTextureGather(Kind)) ||\
+                                                        (IsIntrinsicsKindTextureGather2DRect(Kind)) || \
+                                                        (IsIntrinsicsKindTextureGatherOffset(Kind)) ||\
+                                                        (IsIntrinsicsKindTextureGatherOffset2DRect(Kind)) ||\
+                                                        (IsIntrinsicsKindTextureGatherOffsets(Kind)) ||\
+                                                        (IsIntrinsicsKindTextureGatherOffsets2DRect(Kind)) ||\
+                                                        (IsIntrinsicsKindTexelFetchForMSAA(Kind)))
+
+struct _gcsFUNCTION
+{
+    gcsOBJECT                       object;
+
+    gctUINT32                       argumentArrayCount;
+    gctUINT32                       argumentCount;
+    gcsFUNCTION_ARGUMENT_PTR        arguments;
+    /* the number of arguments be packed away by _packingArugments() */
+    gctUINT32                       packedAwayArgNo;
+
+    gctUINT32                       label;
+    gceFUNCTION_FLAG                flags;
+    gceINTRINSICS_KIND              intrinsicsKind;
+
+    /* Local variables. */
+    gctUINT32                       localVariableCount;
+    gcVARIABLE *                    localVariables;
+
+    /* temp register start index, end index and count */
+    gctUINT32                       tempIndexStart;
+    gctUINT32                       tempIndexEnd;
+    gctUINT32                       tempIndexCount;
+
+    gctUINT                         codeStart;
+    gctUINT                         codeCount;
+
+    gctBOOL                         isRecursion;
+    gctUINT16                       die;
+
+    gctINT                          nameLength;
+    char                            name[1];
+};
+
+#define GetFunctionObject(f)                        (&(f)->object)
+#define GetFunctionArgumentArrayCount(f)            ((f)->argumentArrayCount)
+#define GetFunctionArgumentCount(f)                 ((f)->argumentCount)
+#define GetFunctionPackedAwayArgNo(f)               ((f)->packedAwayArgNo)
+#define GetFunctionArguments(f)                     ((f)->arguments)
+#define GetFunctionLable(f)                         ((f)->label)
+#define GetFunctionFlags(f)                         ((f)->flags)
+#define SetFunctionFlags(f, s)                      ((f)->flags |= (s))
+#define GetFunctionIntrinsicsKind(f)                ((f)->intrinsicsKind)
+#define GetFunctionLocalVariableCount(f)            ((f)->localVariableCount)
+#define GetFunctionLocalVariables(f)                ((f)->localVariables)
+#define GetFunctionTempIndexStart(f)                ((f)->tempIndexStart)
+#define GetFunctionTempIndexEnd(f)                  ((f)->tempIndexEnd)
+#define GetFunctionTempIndexCount(f)                ((f)->tempIndexCount)
+#define GetFunctionCodeStart(f)                     ((f)->codeStart)
+#define GetFunctionCodeCount(f)                     ((f)->codeCount)
+#define GetFunctionIsRecursion(f)                   ((f)->isRecursion)
+#define GetFunctionNameLength(f)                    ((f)->nameLenght)
+#define GetFunctionName(f)                          ((f)->name)
+
+#define SetFunctionIntrinsicsKind(f, kind)          (GetFunctionIntrinsicsKind(f) = kind)
+#define IsFunctionIntrinsicsBuiltIn(f)              (((gcsOBJECT*) (f))->type == gcvOBJ_FUNCTION \
+                                                     ? GetFunctionIntrinsicsKind(f) >= gceINTRIN_source \
+                                                     : gcvFALSE)
+
+#define IsFunctionExtern(f)                         (((gcsOBJECT*) (f))->type == gcvOBJ_FUNCTION \
+                                                     ? (GetFunctionFlags(f) & gcvFUNC_EXTERN) \
+                                                     : (((gcsOBJECT*) (f))->type == gcvOBJ_KERNEL_FUNCTION \
+                                                        ? (GetKFunctionFlags(f) & gcvFUNC_EXTERN) \
+                                                        : gcvFALSE))
+
+#define IsFunctionRecompiler(f)                     (((f)->flags & gcvFUNC_RECOMPILER) != 0)
+#define IsFunctionRecompilerStub(f)                 (((f)->flags & gcvFUNC_RECOMPILER_STUB) != 0)
+#define IsFunctionHasSamplerIndexing(f)             (((f)->flags & gcvFUNC_HAS_SAMPLER_INDEXINED) != 0)
+#define IsFunctionParamAsImgSource0(f)              (((f)->flags & gcvFUNC_PARAM_AS_IMG_SOURCE0) != 0)
+#define IsFunctionUsingSamplerVirtual(f)            (((f)->flags & gcvFUNC_USING_SAMPLER_VIRTUAL) != 0)
+#define IsFunctionHasBigGapInTempReg(f)             (((f)->flags & gcvFUNC_HAS_TEMPREG_BIGGAP) != 0)
+#define IsFunctionNotUsed(f)                        (((f)->flags & gcvFUNC_NOT_USED) != 0)
+
+#define SetFunctionRecompiler(f)                    if (f != gcvNULL) { (f)->flags |= gcvFUNC_RECOMPILER; }
+#define SetFunctionRecompilerStub(f)                if (f != gcvNULL) { (f)->flags |= gcvFUNC_RECOMPILER_STUB; }
+#define SetFunctionHasSamplerIndexing(f)            if (f != gcvNULL) { (f)->flags |= gcvFUNC_HAS_SAMPLER_INDEXINED; }
+#define SetFunctionParamAsImgSource0(f)             if (f != gcvNULL) { (f)->flags |= gcvFUNC_PARAM_AS_IMG_SOURCE0; }
+#define SetFunctionUsingSamplerVirtual(f)           if (f != gcvNULL) { (f)->flags |= gcvFUNC_USING_SAMPLER_VIRTUAL; }
+#define SetFunctionNotUsed(f)                       if (f != gcvNULL) { (f)->flags |= gcvFUNC_NOT_USED; }
+
+/* Same structure, but inside a binary.
+   NOTE: to maintain backward compatibility, new fields must be added after before the name field
+   and the existing field orders have to be maintained.  */
+typedef struct _gcBINARY_FUNCTION
+{
+    gctINT16                        argumentCount;
+    /* the number of arguments be packed away by _packingArugments() */
+    gctUINT16                       packedAwayArgNo;
+    gctINT16                        localVariableCount;
+    gctUINT32                       tempIndexStart;
+    gctUINT32                       tempIndexEnd;
+    gctUINT32                       tempIndexCount;
+    gctUINT32                       codeStart;
+    gctUINT32                       codeCount;
+
+    gctINT16                        label;
+
+    gctINT16                        nameLength;
+    char                            flags[sizeof(gctUINT32)];
+    char                            intrinsicsKind[sizeof(gctUINT32)];
+    gctUINT16                       die;
+
+    char                            name[1];
+}
+* gcBINARY_FUNCTION;
+
+typedef struct _gcsIMAGE_SAMPLER
+{
+    /* Kernel function argument # associated with the image passed to the kernel function */
+    gctUINT8                        imageNum;
+
+    /* Sampler type either passed in as a kernel function argument which will be an argument #
+            or
+           defined as a constant variable inside the program which will be an unsigend integer value*/
+    gctBOOL                         isConstantSamplerType;
+
+    gctUINT32                       samplerType;
+}
+gcsIMAGE_SAMPLER,
+* gcsIMAGE_SAMPLER_PTR;
+
+#define GetImageSamplerImageNum(i)              ((i)->imageNum)
+#define GetImageSamplerIsConstantSamplerType(i) ((i)->isConstantSamplerType)
+#define GetImageSamplerType(i)                  ((i)->samplerType)
+
+/* Same structure, but inside a binary. */
+typedef struct _gcBINARY_IMAGE_SAMPLER
+{
+    /* index to uniform array associated with the sampler */
+    gctUINT16                       uniformIndex;
+    gctBOOL                         isConstantSamplerType;
+
+    /* Kernel function argument # associated with the image passed to the kernel function */
+    gctUINT8                        imageNum;
+
+    /* Sampler type either passed in as a kernel function argument which will be an argument #
+            or
+           defined as a constant variable inside the program which will be an unsigend integer value*/
+    gctUINT32                       samplerType;
+}
+* gcBINARY_IMAGE_SAMPLER;
+
+typedef struct _gcsKERNEL_FUNCTION_PROPERTY
+{
+    gctINT                          propertyType;
+    gctUINT32                       propertySize;
+}
+gcsKERNEL_FUNCTION_PROPERTY,
+* gcsKERNEL_FUNCTION_PROPERTY_PTR;
+
+#define GetKFuncPropType(k)             ((k)->propertyType)
+#define GetKFuncPropSize(k)             ((k)->propertySize)
+
+/* Same structure, but inside a binary. */
+typedef struct _gcBINARY_KERNEL_FUNCTION_PROPERTY
+{
+    gctINT                          propertyType;
+    gctUINT32                       propertySize;
+}
+* gcBINARY_KERNEL_FUNCTION_PROPERTY;
+
+struct _gcsKERNEL_FUNCTION
+{
+    gcsOBJECT                       object;
+
+    /* fields common to gcFUNCTION and gcKERNEL_FUNCTION */
+    gctUINT32                       argumentArrayCount;
+    gctUINT32                       argumentCount;
+    gcsFUNCTION_ARGUMENT_PTR        arguments;
+    /* the number of arguments be packed away by _packingArugments() */
+    gctUINT32                       dummyPackedAwayArgNo; /* not used by kernel, only make it compatible with function*/
+
+    gctUINT32                       label;
+    gceFUNCTION_FLAG                flags;
+    gceINTRINSICS_KIND              intrinsicsKind; /* not used in kernel */
+
+    /* Local variables. */
+    gctUINT32                       localVariableCount;
+    gcVARIABLE *                    localVariables;
+
+    /* temp register start index, end index and count */
+    gctUINT32                       tempIndexStart;
+    gctUINT32                       tempIndexEnd;
+    gctUINT32                       tempIndexCount;
+
+    /*
+    ** the codeEnd only includes the kernel function declaration code count.
+    ** The codeCount includes the kernel function declaration code count and the kernel function call,
+    */
+    gctUINT                         codeStart;
+    gctUINT                         codeEnd;
+    gctUINT                         codeCount;
+
+    gctBOOL                         isRecursion;
+    gctBOOL                         isCalledByEntryKernel;   /* kernel function can be called
+                                                              * by another kernel, cannot remove it
+                                                              * if it is called by main */
+    /* kernel specific fields */
+    gcSHADER                        shader;
+
+    /* kernel info: */
+    /* Local address space size */
+    gctUINT32                       localMemorySize;
+
+    /* Uniforms Args */
+    gctUINT32                       uniformArgumentArrayCount;
+    gctUINT32                       uniformArgumentCount;
+    gcUNIFORM *                     uniformArguments;
+    gctINT                          samplerIndex;
+
+    /* Image-Sampler associations */
+    gctUINT32                       imageSamplerArrayCount;
+    gctUINT32                       imageSamplerCount;
+    gcsIMAGE_SAMPLER_PTR            imageSamplers;
+
+    /* Kernel function properties */
+    gctUINT32                       propertyArrayCount;
+    gctUINT32                       propertyCount;
+    gcsKERNEL_FUNCTION_PROPERTY_PTR properties;
+    gctUINT32                       propertyValueArrayCount;
+    gctUINT32                       propertyValueCount;
+    gctINT_PTR                      propertyValues;
+
+    gctBOOL                         isMain;     /* this kernel is merged with main() */
+    gctUINT16                       die;
+
+    gctINT                          nameLength;
+    char                            name[1];
+};
+
+#define GetKFunctionObject(k)                       (&(k)->object)
+#define GetKFunctionShader(k)                       ((k)->shader)
+#define GetKFunctionArgArrayCount(k)                ((k)->argumentArrayCount)
+#define GetKFunctionArgCount(k)                     ((k)->argumentCount)
+#define GetKFunctionArgs(k)                         ((k)->arguments)
+#define GetKFunctionLable(k)                        ((k)->lable)
+#define GetKFunctionFlags(k)                        ((k)->flags)
+#define SetKFunctionFlags(k, s)                     ((k)->flags |= (s))
+#define GetKFunctionLocalMemorySize(k)              ((k)->localMemorySize)
+#define GetKFunctionUArgArrayCount(k)               ((k)->uniformArgumentArrayCount)
+#define GetKFunctionUArgCount(k)                    ((k)->uniformArgumentCount)
+#define GetKFunctionUArgs(k)                        ((k)->uniformArguments)
+#define GetKFunctionSamplerIndex(k)                 ((k)->samplerIndex)
+#define GetKFunctionISamplerArrayCount(k)           ((k)->imageSamplerArrayCount)
+#define GetKFunctionISamplerCount(k)                ((k)->imageSamplerCount)
+#define SetKFunctionISamplerCount(k, i)             ((k)->imageSamplerCount = i)
+#define GetKFunctionISamplers(k)                    ((k)->imageSamplers)
+#define GetKFunctionLocalVarCount(k)                ((k)->localVariableCount)
+#define GetKFunctionLocalVars(k)                    ((k)->localVariables)
+#define GetKFunctionTempIndexStart(k)               ((k)->tempIndexStart)
+#define GetKFunctionTempIndexEnd(k)                 ((k)->tempIndexEnd)
+#define GetKFunctionTempIndexCount1(k)              ((k)->tempIndexCount)
+#define GetKFunctionPropertyArrayCount(k)           ((k)->propertyArrayCount)
+#define GetKFunctionPropertyCount(k)                ((k)->propertyCount)
+#define GetKFunctionProperties(k)                   ((k)->properties)
+#define GetKFunctionPropertyValueArrayCount(k)      ((k)->propertyValueArrayCount)
+#define GetKFunctionPropertyValueCount(k)           ((k)->propertyValueCount)
+#define GetKFunctionPropertyValues(k)               ((k)->propertyValues)
+#define GetKFunctionCodeStart(k)                    ((k)->codeStart)
+#define GetKFunctionCodeCount(k)                    ((k)->codeCount)
+#define GetKFunctionCodeEnd(k)                      ((k)->codeEnd)
+#define GetKFunctionIsMain(k)                       ((k)->isMain)
+#define GetKFunctionNameLength(k)                   ((k)->nameLength)
+#define GetKFunctionName(k)                         ((k)->name)
+
+
+/* Same structure, but inside a binary.
+   NOTE: to maintain backward compatibility, new fields must be added after before the name field
+   and the existing field orders have to be maintained.  */
+typedef struct _gcBINARY_KERNEL_FUNCTION
+{
+    gctINT16                        argumentCount;
+    gctINT16                        label;
+    char                            localMemorySize[sizeof(gctUINT32)];
+    gctINT16                        uniformArgumentCount;
+    gctINT16                        samplerIndex;
+    gctINT16                        imageSamplerCount;
+    gctINT16                        localVariableCount;
+    gctUINT32                       tempIndexStart;
+    gctUINT32                       tempIndexEnd;
+    gctUINT32                       tempIndexCount;
+    gctINT16                        propertyCount;
+    gctINT16                        propertyValueCount;
+
+    gctUINT32                       codeStart;
+    gctUINT32                       codeCount;
+    gctUINT32                       codeEnd;
+
+    gctUINT16                       isMain;
+    gctUINT16                       die;
+
+    gctINT16                        nameLength;
+    char                            flags[sizeof(gctUINT32)];
+    char                            name[1];
+}
+* gcBINARY_KERNEL_FUNCTION;
+
+/* Index into current instruction. */
+typedef enum _gcSHADER_INSTRUCTION_INDEX
+{
+    gcSHADER_OPCODE,
+    gcSHADER_SOURCE0,
+    gcSHADER_SOURCE1,
+}
+gcSHADER_INSTRUCTION_INDEX;
+
+typedef struct _gcSHADER_LINK * gcSHADER_LINK;
+
+/* Structure defining a linked references for a label. */
+struct _gcSHADER_LINK
+{
+    gcSHADER_LINK                   next;
+    gctUINT                         referenced;
+};
+
+#define GetLinkNext(l)              ((l)->next)
+#define GetLinkRef(l)               ((l)->referenced)
+
+typedef struct _gcSHADER_LABEL * gcSHADER_LABEL;
+
+/* Structure defining a label. */
+struct _gcSHADER_LABEL
+{
+    gcSHADER_LABEL                  next;
+    gctUINT                         label;
+    gctUINT                         defined;
+    gcSHADER_LINK                   referenced;
+    gcFUNCTION                      function;       /* the function that is corresponding to this label */
+};
+
+#define GetLabelNext(l)                 ((l)->next)
+#define GetLableID(l)                   ((l)->label)
+#define GetLableDefined(l)              ((l)->defined)
+#define GetLableRef(l)                  ((l)->referenced)
+#define GetLableFunction(l)             ((l)->function)
+
+typedef struct _gcsVarTempRegInfo
+{
+    gcOUTPUT           varying;
+    gctUINT32          streamoutSize;  /* size to write on feedback buffer */
+    gctINT             tempRegCount;   /* number of temp register assigned
+                                          to this variable */
+    gctBOOL            isArray;
+    gcSHADER_TYPE *    tempRegTypes;   /* the type for each temp reg */
+}
+gcsVarTempRegInfo;
+
+typedef struct _gcsTFBVarying
+{
+    gctSTRING name;
+    gctINT    arraySize;
+    gctBOOL   isWholeTFBed;
+    gctBOOL   isArray;
+    gcOUTPUT  output;
+    gctBOOL   isBuiltinArray;
+    gctINT    builtinArrayIdx;
+    gctBOOL   bEndOfInterleavedBuffer;
+} gcsTFBVarying;
+
+typedef struct _gcBINARY_TFBVarying
+{
+    gctUINT16                       outputIndex;
+    gctINT16                        arraySize;
+    gctINT16                        isWholeTFBed;
+    gctINT16                        isArray;
+    gctINT16                        isBuiltinArray;
+    gctINT16                        builtinArrayIdx;
+    gctINT16                        bEndOfInterleavedBuffer;
+    gctINT16                        nameLength;
+    char                            name[1];
+}
+* gcBINARY_TFBVarying;
+
+typedef struct _gcsTRANSFORM_FEEDBACK
+{
+    gctUINT32                       varyingCount;
+    /* pointer to varyings to be streamed out */
+    gcsTFBVarying *                 varyings;
+
+    gceFEEDBACK_BUFFER_MODE         bufferMode;
+    /* driver set to 1 if transform feedback is active and not
+       paused, 0 if inactive or paused */
+    gcUNIFORM                       stateUniform;
+    /* the temp register info for each varying */
+    gcsVarTempRegInfo *             varRegInfos;
+    union {
+        /* array of uniform for separate transform feedback buffers */
+        gcUNIFORM *                 separateBufUniforms;
+        /* transfom feedback buffer for interleaved mode */
+        gcUNIFORM                   interleavedBufUniform;
+    } feedbackBuffer;
+    gctINT                          shaderTempCount;
+    /* total size to write to interleaved buffer for one vertex */
+    gctUINT32                       totalSize;
+}
+gcsTRANSFORM_FEEDBACK;
+
+#define GetFeedbackVaryingCount(f)                  ((f)->varyingCount)
+#define GetFeedbackVaryings(f)                      ((f)->varyings)
+#define GetFeedbackBufferMode(f)                    ((f)->bufferMode)
+#define GetFeedbackStateUniform(f)                  ((f)->stateUniform)
+#define GetFeedbackVarRegInfos(f)                   ((f)->varRegInfos)
+#define GetFeedbackSeparateBufUniforms(f)           ((f)->feedbackBuffer.separateBufUniforms)
+#define GetFeedbackInterleavedBufUniform(f)         ((f)->feedbackBuffer.interleavedBufUniform)
+#define GetFeedbackShaderTempCount(f)               ((f)->shaderTempCount)
+#define GetFeedbackTotalSize(f)                     ((f)->totalSize)
+
+typedef enum _gcSHADER_FLAGS
+{
+    gcSHADER_FLAG_OLDHEADER                 = 0x01, /* the old header word 5 is gcdSL_IR_VERSION,
+                                                         which always be 0x01 */
+    gcSHADER_FLAG_HWREG_ALLOCATED           = 0x02, /* the shader is HW Register allocated
+                                                         no need to geneated MOVA implicitly */
+    gcSHADER_FLAG_CONST_HWREG_ALLOCATED     = 0x04, /* the shader is HW const Register allocated */
+    gcSHADER_FLAG_HAS_UNSIZED_SBO           = 0x08, /* the shader has unsized array of Storage Buffer Object */
+    gcSHADER_FLAG_HAS_VERTEXID_VAR          = 0x10, /* the shader has vertexId variable */
+    gcSHADER_FLAG_HAS_INSTANCEID_VAR        = 0x20, /* the shader has instanceId variable */
+    gcSHADER_FLAG_HAS_INTRINSIC_BUILTIN     = 0x40, /* the shader has intrinsic builtins */
+    gcSHADER_FLAG_HAS_EXTERN_FUNCTION       = 0x80, /* the shader has extern functions */
+    gcSHADER_FLAG_HAS_EXTERN_VARIABLE       = 0x100, /* the shader has extern variables */
+    gcSHADER_FLAG_NEED_PATCH_FOR_CENTROID   = 0x200, /* the shader uses centroid varyings as
+                                                         the argument of interpolate functions */
+    gcSHADER_FLAG_HAS_BASE_MEMORY_ADDR      = 0x400, /* the shader has base memory address, for CL only. */
+    gcSHADER_FLAG_HAS_LOCAL_MEMORY_ADDR     = 0x800, /* the shader has local memory address. */
+    gcSHADER_FLAG_HAS_INT64                 = 0x1000, /* the shader has 64 bit integer data and operation. */
+    gcSHADER_FLAG_HAS_IMAGE_QUERY           = 0x2000, /* the shader has image query */
+    gcSHADER_FLAG_HAS_VIV_VX_EXTENSION      = 0x4000, /* the shader has Vivante VX extension */
+    gcSHADER_FLAG_USE_LOCAL_MEM             = 0x8000, /* the shader use local memory */
+    gcSHADER_FLAG_VP_TWO_SIDE_ENABLE        = 0x10000, /* the shader use two side, for GL fragment shader only. */
+    gcSHADER_FLAG_CLAMP_OUTPUT_COLOR        = 0x20000, /* Clamp the output color, for GL shader only. */
+    gcSHADER_FLAG_HAS_INT64_PATCH           = 0x40000, /* the shader has 64 bit integer data and operation patch (recompile). */
+    gcSHADER_FLAG_AFTER_LINK                = 0x80000, /* the shader is linked(gcLinkProgram/gcLinkShaders/gcLinkKernel). */
+    gcSHADER_FLAG_LOADED_KERNEL             = 0x100000, /* shader has loaded a specified kernel function, for OCL shader only. */
+    gcSHADER_FLAG_FORCE_ALL_OUTPUT_INVARIANT= 0x200000, /* Force all outputs to be invariant. */
+    gcSHADER_FLAG_CONSTANT_MEMORY_REFERENCED= 0x400000, /* constant memory reference in the shader (library) through linking. */
+    gcSHADER_FLAG_HAS_DEFINE_MAIN_FUNC      = 0x800000, /* Whether the shader defines a main function, for GL shader only. */
+    gcSHADER_FLAG_ENABLE_MULTI_GPU          = 0x1000000, /* whether enable multi-GPU. */
+    gcSHADER_FLAG_HAS_VIV_GCSL_DRIVER_IMAGE = 0x2000000, /* the shader has OCL option `-cl-viv-gcsl-driver-image */
+} gcSHADER_FLAGS;
+
+#define gcShaderIsOldHeader(Shader)             (((Shader)->flags & gcSHADER_FLAG_OLDHEADER) != 0)
+#define gcShaderHwRegAllocated(Shader)          ((Shader)->flags & gcSHADER_FLAG_HWREG_ALLOCATED)
+#define gcShaderConstHwRegAllocated(Shader)     ((Shader)->flags & gcSHADER_FLAG_CONST_HWREG_ALLOCATED)
+#define gcShaderHasUnsizedSBO(Shader)           (((Shader)->flags & gcSHADER_FLAG_HAS_UNSIZED_SBO) != 0)
+#define gcShaderHasVertexIdVar(Shader)          (((Shader)->flags & gcSHADER_FLAG_HAS_VERTEXID_VAR) != 0)
+#define gcShaderHasInstanceIdVar(Shader)        (((Shader)->flags & gcSHADER_FLAG_HAS_INSTANCEID_VAR) != 0)
+#define gcShaderHasIntrinsicBuiltin(Shader)     (((Shader)->flags & gcSHADER_FLAG_HAS_INTRINSIC_BUILTIN) != 0)
+#define gcShaderHasExternFunction(Shader)       (((Shader)->flags & gcSHADER_FLAG_HAS_EXTERN_FUNCTION) != 0)
+#define gcShaderHasExternVariable(Shader)       (((Shader)->flags & gcSHADER_FLAG_HAS_EXTERN_VARIABLE) != 0)
+#define gcShaderNeedPatchForCentroid(Shader)    (((Shader)->flags & gcSHADER_FLAG_NEED_PATCH_FOR_CENTROID) != 0)
+#define gcShaderHasBaseMemoryAddr(Shader)       (((Shader)->flags & gcSHADER_FLAG_HAS_BASE_MEMORY_ADDR) != 0)
+#define gcShaderHasLocalMemoryAddr(Shader)      (((Shader)->flags & gcSHADER_FLAG_HAS_LOCAL_MEMORY_ADDR) != 0)
+#define gcShaderHasInt64(Shader)                (((Shader)->flags & gcSHADER_FLAG_HAS_INT64) != 0)
+#define gcShaderHasInt64Patch(Shader)           (((Shader)->flags & gcSHADER_FLAG_HAS_INT64_PATCH) != 0)
+#define gcShaderHasImageQuery(Shader)           (((Shader)->flags & gcSHADER_FLAG_HAS_IMAGE_QUERY) != 0)
+#define gcShaderHasVivVxExtension(Shader)       (((Shader)->flags & gcSHADER_FLAG_HAS_VIV_VX_EXTENSION) != 0)
+#define gcShaderHasVivGcslDriverImage(Shader)   (((Shader)->flags & gcSHADER_FLAG_HAS_VIV_GCSL_DRIVER_IMAGE) != 0)
+#define gcShaderUseLocalMem(Shader)             (((Shader)->flags & gcSHADER_FLAG_USE_LOCAL_MEM) != 0)
+#define gcShaderVPTwoSideEnable(Shader)         (((Shader)->flags & gcSHADER_FLAG_VP_TWO_SIDE_ENABLE) != 0)
+#define gcShaderClampOutputColor(Shader)        (((Shader)->flags & gcSHADER_FLAG_CLAMP_OUTPUT_COLOR) != 0)
+#define gcShaderAfterLink(Shader)               (((Shader)->flags & gcSHADER_FLAG_AFTER_LINK) != 0)
+#define gcShaderHasLoadedKernel(Shader)         (((Shader)->flags & gcSHADER_FLAG_LOADED_KERNEL) != 0)
+#define gcShaderForceAllOutputInvariant(Shader) (((Shader)->flags & gcSHADER_FLAG_FORCE_ALL_OUTPUT_INVARIANT) != 0)
+#define gcShaderConstantMemoryReferenced(Shader) (((Shader)->flags & gcSHADER_FLAG_CONSTANT_MEMORY_REFERENCED) != 0)
+#define gcShaderHasDefineMainFunc(Shader)       (((Shader)->flags & gcSHADER_FLAG_HAS_DEFINE_MAIN_FUNC) != 0)
+#define gcShaderEnableMultiGPU(Shader)          (((Shader)->flags & gcSHADER_FLAG_ENABLE_MULTI_GPU) != 0)
+
+#define gcShaderGetFlag(Shader)                 (Shader)->flags)
+
+#define gcShaderSetIsOldHeader(Shader)          do { (Shader)->flags |= gcSHADER_FLAG_OLDHEADER; } while (0)
+#define gcShaderSetHwRegAllocated(Shader)       do { (Shader)->flags |= gcSHADER_FLAG_HWREG_ALLOCATED; } while (0)
+#define gcShaderSetConstHwRegAllocated(Shader)  do { (Shader)->flags |= gcSHADER_FLAG_CONST_HWREG_ALLOCATED; } while (0)
+#define gcShaderSetHasUnsizedSBO(Shader)        do { (Shader)->flags |= gcSHADER_FLAG_HAS_UNSIZED_SBO; } while (0)
+#define gcShaderSetHasVertexIdVar(Shader)       do { (Shader)->flags |= gcSHADER_FLAG_HAS_VERTEXID_VAR; } while (0)
+#define gcShaderSetHasInstanceIdVar(Shader)     do { (Shader)->flags |= gcSHADER_FLAG_HAS_INSTANCEID_VAR; } while (0)
+#define gcShaderSetHasIntrinsicBuiltin(Shader)  do { (Shader)->flags |= gcSHADER_FLAG_HAS_INTRINSIC_BUILTIN; } while (0)
+#define gcShaderClrHasIntrinsicBuiltin(Shader)  do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_INTRINSIC_BUILTIN; } while (0)
+#define gcShaderSetHasExternFunction(Shader)    do { (Shader)->flags |= gcSHADER_FLAG_HAS_EXTERN_FUNCTION; } while (0)
+#define gcShaderClrHasExternFunction(Shader)    do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_EXTERN_FUNCTION; } while (0)
+#define gcShaderSetHasExternVariable(Shader)    do { (Shader)->flags |= gcSHADER_FLAG_HAS_EXTERN_VARIABLE; } while (0)
+#define gcShaderClrHasExternVariable(Shader)    do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_EXTERN_VARIABLE; } while (0)
+#define gcShaderSetNeedPatchForCentroid(Shader) do { (Shader)->flags |= gcSHADER_FLAG_NEED_PATCH_FOR_CENTROID; } while (0)
+#define gcShaderClrNeedPatchForCentroid(Shader) do { (Shader)->flags &= ~gcSHADER_FLAG_NEED_PATCH_FOR_CENTROID; } while (0)
+#define gcShaderSetHasBaseMemoryAddr(Shader)    do { (Shader)->flags |= gcSHADER_FLAG_HAS_BASE_MEMORY_ADDR; } while (0)
+#define gcShaderClrHasBaseMemoryAddr(Shader)    do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_BASE_MEMORY_ADDR; } while (0)
+#define gcShaderSetHasLocalMemoryAddr(Shader)   do { (Shader)->flags |= gcSHADER_FLAG_HAS_LOCAL_MEMORY_ADDR; } while (0)
+#define gcShaderClrHasLocalMemoryAddr(Shader)   do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_LOCAL_MEMORY_ADDR; } while (0)
+#define gcShaderSetHasInt64(Shader)             do { (Shader)->flags |= gcSHADER_FLAG_HAS_INT64; } while (0)
+#define gcShaderClrHasInt64(Shader)             do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_INT64; } while (0)
+#define gcShaderSetHasInt64Patch(Shader)        do { (Shader)->flags |= gcSHADER_FLAG_HAS_INT64_PATCH; } while (0)
+#define gcShaderClrHasInt64Patch(Shader)        do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_INT64_PATCH; } while (0)
+#define gcShaderSetHasImageQuery(Shader)        do { (Shader)->flags |= gcSHADER_FLAG_HAS_IMAGE_QUERY; } while (0)
+#define gcShaderClrHasImageQuery(Shader)        do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_IMAGE_QUERY; } while (0)
+#define gcShaderSetHasVivVxExtension(Shader)    do { (Shader)->flags |= gcSHADER_FLAG_HAS_VIV_VX_EXTENSION; } while (0)
+#define gcShaderClrHasVivVxExtension(Shader)    do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_VIV_VX_EXTENSION; } while (0)
+#define gcShaderSetHasVivGcslDriverImage(Shader)    do { (Shader)->flags |= gcSHADER_FLAG_HAS_VIV_GCSL_DRIVER_IMAGE; } while (0)
+#define gcShaderClrHasVivGcslDriverImage(Shader)    do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_VIV_GCSL_DRIVER_IMAGE; } while (0)
+#define gcShaderSetVPTwoSideEnable(Shader)      do { (Shader)->flags |= gcSHADER_FLAG_VP_TWO_SIDE_ENABLE; } while (0)
+#define gcShaderClrVPTwoSideEnable(Shader)      do { (Shader)->flags &= ~gcSHADER_FLAG_VP_TWO_SIDE_ENABLE; } while (0)
+#define gcShaderSetClampOutputColor(Shader)     do { (Shader)->flags |= gcSHADER_FLAG_CLAMP_OUTPUT_COLOR; } while (0)
+#define gcShaderClrClampOutputColor(Shader)     do { (Shader)->flags &= ~gcSHADER_FLAG_CLAMP_OUTPUT_COLOR; } while (0)
+#define gcShaderSetAfterLink(Shader)            do { (Shader)->flags |= gcSHADER_FLAG_AFTER_LINK; } while (0)
+#define gcShaderClrAfterLink(Shader)            do { (Shader)->flags &= ~gcSHADER_FLAG_AFTER_LINK; } while (0)
+#define gcShaderSetLoadedKernel(Shader)         do { (Shader)->flags |= gcSHADER_FLAG_LOADED_KERNEL; } while (0)
+#define gcShaderClrLoadedKernel(Shader)         do { (Shader)->flags &= ~gcSHADER_FLAG_LOADED_KERNEL; } while (0)
+#define gcShaderSetAllOutputInvariant(Shader)   do { (Shader)->flags |= gcSHADER_FLAG_FORCE_ALL_OUTPUT_INVARIANT; } while (0)
+#define gcShaderClrAllOutputInvariant(Shader)   do { (Shader)->flags &= ~gcSHADER_FLAG_FORCE_ALL_OUTPUT_INVARIANT; } while (0)
+#define gcShaderSetConstantMemoryReferenced(Shader)   do { (Shader)->flags |= gcSHADER_FLAG_CONSTANT_MEMORY_REFERENCED; } while (0)
+#define gcShaderClrConstantMemoryReferenced(Shader)   do { (Shader)->flags &= ~gcSHADER_FLAG_CONSTANT_MEMORY_REFERENCED; } while (0)
+#define gcShaderSetHasDefineMainFunc(Shader)    do { (Shader)->flags |= gcSHADER_FLAG_HAS_DEFINE_MAIN_FUNC; } while (0)
+#define gcShaderClrHasDefineMainFunc(Shader)    do { (Shader)->flags &= ~gcSHADER_FLAG_HAS_DEFINE_MAIN_FUNC; } while (0)
+#define gcShaderSetEnableMultiGPU(Shader)       do { (Shader)->flags |= gcSHADER_FLAG_ENABLE_MULTI_GPU; } while (0)
+#define gcShaderClrEnableMultiGPU(Shader)       do { (Shader)->flags &= ~gcSHADER_FLAG_ENABLE_MULTI_GPU; } while (0)
+
+#define gcShaderSetFlag(Shader, Flag)           do { (Shader)->flags = (Flag); } while (0)
+
+typedef struct _gcLibraryList gcLibraryList;
+
+struct _gcLibraryList
+{
+    gcSHADER        lib;
+    /* temp register mapping table */
+    gctUINT32       tempMappingTableEntries;
+    gctUINT32 *     tempMappingTable;
+    /* uniform mapping table */
+    gctUINT32       uniformMappingTableEntries;
+    gctUINT16 *     uniformMappingTable;
+
+    gcLibraryList * next;
+};
+
+#define gcMAX_SHADERS_IN_LINK_GOURP 6
+#define gcMAX_SHADERS_IN_PROGRAM    6
+
+typedef enum _gcsSHADER_GROUP_SHADER_KIND
+{
+    gceSGSK_VERTEX_SHADER       = 0,
+    gceSGSK_CL_SHADER           = 1, /* openCL shader */
+    gceSGSK_COMPUTE_SHADER      = 1, /* OGL compute shader */
+    gceSGSK_TC_SHADER           = 2, /* Tessellation control shader */
+    gceSGSK_TE_SHADER           = 3, /* Tessellation evaluation shader */
+    gceSGSK_GEOMETRY_SHADER     = 4,
+    gceSGSK_FRAGMENT_SHADER     = 5
+} gcsSHADER_GROUP_SHADER_KIND;
+
+typedef struct _gcsSHADERGROUP
+{
+    gcSHADER    shaderGroup[gcMAX_SHADERS_IN_LINK_GOURP];
+    gctBOOL     validGroup;
+    gctBOOL     hasComputeOrCLShader;
+} gcsShaderGroup;
+
+typedef enum _gcTESSPRIMITIVEMODE
+{
+    gcTESS_PMODE_TRIANGLE = 0,
+    gcTESS_PMODE_QUAD,
+    gcTESS_PMODE_ISOLINE
+} gcTessPrimitiveMode;
+
+typedef enum _gcTESSVERTEXSPACING
+{
+    gcTESS_SPACING_EQUAL = 0, /* equal_spacing */
+    gcTESS_SPACING_EVEN, /* fractional_even_spacing */
+    gcTESS_SPACING_ODD            /* fractional_odd_spacing */
+} gcTessVertexSpacing;
+
+typedef enum _gcTESSORDERING
+{
+    gcTESS_ORDER_CCW = 0, /* Counter Clockwise */
+    gcTESS_ORDER_CW               /* Clockwise */
+} gcTessOrdering;
+
+typedef enum _gcGEOPRIMITIVE
+{
+    gcGEO_POINTS = 0,
+    gcGEO_LINES,
+    gcGEO_LINES_ADJACENCY,
+    gcGEO_TRIANGLES,
+    gcGEO_TRIANGLES_ADJACENCY,
+    gcGEO_LINE_STRIP,
+    gcGEO_TRIANGLE_STRIP,
+} gcGeoPrimitive;
+
+typedef struct _gcCOMPUTELAYOUT
+{
+    /* Compute shader layout qualifiers */
+    gctUINT32           workGroupSize[3];  /* local group size in the first(0), second(1), and
+                                               third(2) dimension */
+    /* Is WorkGroupSize fixed? If no, compiler can adjust it. */
+    gctBOOL             isWorkGroupSizeFixed;
+
+    /* If WorkGroupSize has been adjusted. */
+    gctBOOL             isWorkGroupSizeAdjusted;
+
+    /* Default workGroupSize. */
+    gctUINT32           adjustedWorkGroupSize;
+
+    /* The factor of reducing WorkGroupSize, the default value is 0. */
+    gctUINT16           workGroupSizeFactor[3];
+} gcComputeLayout;
+
+typedef struct _gcTCSLAYOUT
+{
+    /* Tesselation Control Shader layout */
+    gctINT                 tcsPatchOutputVertices;
+    gcUNIFORM              tcsInputVerticesUniform;
+    gctINT                 tcsPatchInputVertices;
+} gcTCSLayout;
+
+typedef struct _gcTESLAYOUT
+{
+    /* Tessellation Evaluation Shader layout qualifiers*/
+    gcTessPrimitiveMode   tessPrimitiveMode;
+    gcTessVertexSpacing   tessVertexSpacing;
+    gcTessOrdering        tessOrdering;
+    gctBOOL               tessPointMode;
+    gctINT                tessPatchInputVertices;
+} gcTESLayout;
+
+typedef struct _gcGEOLAYOUT
+{
+    /*  Geometry Shader layout */
+    /* times of geometry shader executable is invoked for each input primitive received */
+    gctINT                geoInvocations;
+    /* the maximum number of vertices the shader will ever emit in a single invocation */
+    gctINT                geoMaxVertices;
+    /* type of input primitive accepted by geometry shader */
+    gcGeoPrimitive        geoInPrimitive;
+    /* type of output primitive accepted by geometry shader */
+    gcGeoPrimitive        geoOutPrimitive;
+} gcGEOLayout;
+
+/* The structure that defines the gcSHADER object to the outside world. */
+struct _gcSHADER
+{
+    /* The base object. */
+    gcsOBJECT                   object;
+    gceAPI                      clientApiVersion;  /* client API version. */
+    gctUINT                     _id;                /* unique id used for triage */
+    gctUINT                     _stringId;        /* unique id generated by shader source. */
+    gctUINT                     _constVectorId;     /* unique constant uniform vector id */
+    gctUINT                     _dummyUniformCount;
+    gctUINT                     _tempRegCount;      /* the temp register count of the shader */
+    gctUINT                     _maxLocalTempRegCount; /* the maximum # of temp register set aside to local use in OCL */
+
+    /* Flag whether enable default UBO.*/
+    gctBOOL                     enableDefaultUBO;
+    gctINT                      _defaultUniformBlockIndex; /* Default uniform block index */
+
+    /* Index of the uniform block that hold the const uniforms generated by compiler.*/
+    gctINT                      constUniformBlockIndex;
+
+    /* The size of the uniform block that hold the const uniforms. */
+    gctINT                      constUBOSize;
+
+    /* A memory buffer to store constant uniform. */
+    gctUINT32 *                 constUBOData;
+
+    /* Frontend compiler version */
+    gctUINT32                   compilerVersion[2];
+
+    /* Type of shader. */
+    gcSHADER_KIND               type;
+
+    /* Flags */
+    gcSHADER_FLAGS              flags;
+
+    /* Maximum of kernel function arguments, used to calculation the starting uniform index */
+    gctUINT32                   maxKernelFunctionArgs;
+
+    /* Global uniform count, used for cl kernel patching. */
+    gctUINT32                   globalUniformCount;
+
+    /* Constant memory address space size for openCL */
+    gctUINT32                   constantMemorySize;
+    gctCHAR    *                constantMemoryBuffer;
+
+    /* Private memory address space size for openCL */
+    gctUINT32                   privateMemorySize;
+
+    /* Local memory address space size for openCL, inherited from chosen kernel function */
+    gctUINT32                   localMemorySize;
+
+    /* buffer to keep non basic type names for openCL */
+    gctUINT32                   typeNameBufferSize;
+    gctCHAR    *                typeNameBuffer;
+
+    /* Attributes. */
+    gctUINT32                   attributeArraySize;
+    gctUINT32                   attributeCount;
+    gcATTRIBUTE *               attributes;
+
+    gctUINT32                   builtinAttributeCount;
+    gcATTRIBUTE                 builtinAttributes[2];
+
+    /* Uniforms. */
+    gctUINT32                   uniformArraySize;
+    gctUINT32                   uniformCount;
+    gctUINT32                   uniformVectorCount;  /* the vector count of all uniforms */
+    gcUNIFORM *                 uniforms;
+
+    gctINT                      samplerIndex;
+
+    /* HALTI extras: Uniform block. */
+    gctUINT32                   uniformBlockArraySize;
+    gctUINT32                   uniformBlockCount;
+    gcsUNIFORM_BLOCK *          uniformBlocks;
+
+    /* HALTI extras: input buffer locations. */
+    gctUINT32                   inputLocationArraySize;
+    gctUINT32                   inputLocationCount;
+    gctINT *                    inputLocations;
+
+    /* HALTI extras: input buffer locations. */
+    gctUINT32                   outputLocationArraySize;
+    gctUINT32                   outputLocationCount;
+    gctINT *                    outputLocations;
+
+    /* ES30 extras: default block uniform locations. */
+    gctUINT32                   uniformLocationArraySize;
+    gctUINT32                   uniformLocationCount;
+    gctINT *                    uniformLocations;
+
+    /* Outputs. */
+    gctUINT32                   outputArraySize;    /* the size of 'outputs' be allocated */
+    gctUINT32                   outputCount;        /* the output current be added, each
+                                                       item in an array count as one output */
+    gcOUTPUT *                  outputs;            /* pointer to the output array */
+
+    /* Global variables. */
+    gctUINT32                   variableArraySize;
+    gctUINT32                   variableCount;
+    gcVARIABLE *                variables;
+
+    /* ES 3.1 : storage block. */
+    gctUINT32                   storageBlockArraySize;
+    gctUINT32                   storageBlockCount;
+    gcsSTORAGE_BLOCK *          storageBlocks;
+
+    gctBOOL                     enableDefaultStorageBlock;
+    gctUINT16                   _defaultStorageBlock;
+
+    /* ES 3.1+ : io block. */
+    gctUINT32                   ioBlockArraySize;
+    gctUINT32                   ioBlockCount;
+    gcsIO_BLOCK *               ioBlocks;
+
+    /* Functions. */
+    gctUINT32                   functionArraySize;
+    gctUINT32                   functionCount;
+    gcFUNCTION *                functions;
+    gcFUNCTION                  currentFunction;
+
+    /* Kernel Functions. */
+    gctUINT32                   kernelFunctionArraySize;
+    gctUINT32                   kernelFunctionCount;
+    gcKERNEL_FUNCTION *         kernelFunctions;
+    gcKERNEL_FUNCTION           currentKernelFunction;
+
+    union {
+        gcComputeLayout   compute;
+        gcTCSLayout       tcs;
+        gcTESLayout       tes;
+        gcGEOLayout       geo;
+    } shaderLayout;
+
+    /* Code. */
+    gctUINT32                   codeCount;
+    gctUINT                     lastInstruction;
+    gcSHADER_INSTRUCTION_INDEX  instrIndex;
+    gcSHADER_LABEL              labels;
+    gcSL_INSTRUCTION            code;
+
+    gctINT *                    loadUsers;
+
+    /* load-time optimization uniforms */
+    gctINT                      ltcUniformCount;      /* load-time constant uniform count */
+    gctUINT                     ltcUniformBegin;      /* the begin offset of ltc in uniforms */
+    gcSHADER_LIST               ltcCodeUniformMappingList; /* Map code index to the uniform index. */
+    gctUINT                     ltcInstructionCount;  /* the total instruction count of the LTC expressions */
+    gcSL_INSTRUCTION            ltcExpressions;       /* the expression array for ltc uniforms, which is a list of instructions */
+
+    PLTCValue                   ltcUniformValues;  /* Save the LTC uniform values that can be evaluated within link time. */
+
+#if gcdUSE_WCLIP_PATCH
+    gctBOOL                     vsPositionZDependsOnW;    /* for wClip */
+    gcSHADER_LIST               wClipTempIndexList;
+    gcSHADER_LIST               wClipUniformIndexList;
+#endif
+
+    /* Optimization option. */
+    gctUINT                     optimizationOption;
+
+    /* Transform feedback varyings */
+    gcsTRANSFORM_FEEDBACK       transformFeedback;
+
+    /* Source code string */
+    gctUINT                     sourceLength;            /* including terminating '\0' */
+    gctSTRING                   source;
+
+    /* a list of library linked to this shader */
+    gcLibraryList *             libraryList;
+#if gcdSHADER_SRC_BY_MACHINECODE
+    /* It is used to do high level GLSL shader detection, and give a BE a replacement index hint to replace
+       automatically compiled machine code with manually written extremely optimized machine code. So it is
+       a dynamic info based on driver client code, and supposedly it is not related to gcSL structure. So DO
+       NOT CONSIDER IT IN LOAD/SAVE ROUTINES. Putting this info in gcSL structure because we don't want to
+       break existed prototype of gcLinkShaders. If later somebody find another better place to pass this info
+       into gcLinkShaders, feel free to change it */
+    gctUINT32                   replaceIndex;
+#endif
+
+    gctBOOL                     isDual16Shader;
+    /* for recompile only - whether the recompile's master shader is dual16 or not,
+       if yes, we need to force recompile shader to be dual16 if possible */
+    gctBOOL                     isMasterDual16Shader;
+
+    gctUINT32                   RARegWaterMark;
+    gctUINT32                   RATempReg;
+    gctUINT32                   RAHighestPriority;
+
+    /* Disable EarlyZ for this program. */
+    gctBOOL                     disableEarlyZ;
+
+    /* all the blend modes the shader needs to do */
+    gceLAYOUT_QUALIFIER         outputBlends;
+
+    /* whether the shader enable early fragment test, only affect fragment shader. */
+    gctBOOL                     useEarlyFragTest;
+
+    /* Use gl_LastFragData[]. */
+    gctBOOL                     useLastFragData;
+
+    /* whether the shader's input vertex count coming from driver, only affect TCS shader.
+       during recompilation, this flag is set to be true. */
+    gctBOOL                     useDriverTcsPatchInputVertices;
+
+    /* whether this shader has any not-states-related error that can be detected by FE
+       but specs requires that those errors are treated as link-time errors. */
+    gceSTATUS                   hasNotStagesRelatedLinkError;
+
+    void *                      debugInfo;
+    gceFRAGOUT_USAGE            fragOutUsage;
+
+#if _SUPPORT_LONG_ULONG_DATA_TYPE
+    /* used to modefy the index of instruction when need to insert instruction into the shader when recompile */
+    gctUINT                     InsertCount;
+    gctUINT                     InstNum;
+#endif
+
+};
+
+/* Defines for OCL on reserved temp registers used for memory space addresses */
+/* Once add a new entry, please also do the corresponding change in gc_vsc_vir_ir.h. */
+#define _gcdOCL_PrivateMemoryAddressRegIndex     1  /*private memory address register index */
+#define _gcdOCL_LocalMemoryAddressRegIndex       2  /*local memory address register index for the local variables within kernel function */
+#define _gcdOCL_ParmLocalMemoryAddressRegIndex   3  /*local memory address register index for the local parameters */
+#define _gcdOCL_ConstantMemoryAddressRegIndex    4  /*constant memory address register index */
+#define _gcdOCL_PrintfStartMemoryAddressRegIndex 5  /*printf start memory address register index */
+#define _gcdOCL_PrintfEndMemoryAddressRegIndex   6  /*printf end memory address register index */
+#define _gcdOCL_PreScaleGlobalIdRegIndex         7  /*pre-scale global ID register index */
+#define _gcdOCL_NumMemoryAddressRegs             8  /*number of memory address registers */
+#define _gcdOCL_MaxLocalTempRegs                16  /*maximum # of local temp register including the reserved ones for base addresses to memory spaces*/
+
+#define gcShaderIsDesktopGL(S)                  ((S)->clientApiVersion == gcvAPI_OPENGL)
+#define gcShaderIsOpenVG(S)                     ((S)->clientApiVersion == gcvAPI_OPENVG || (((S)->compilerVersion[0] & 0xffff) == _SHADER_VG_TYPE))
+
+#define GetShaderObject(s)                      ((s)->object)
+#define GetShaderClientApiVersion(s)            ((s)->clientApiVersion)
+#define GetShaderID(s)                          ((s)->_id)
+#define GetShaderConstVectorId(s)               ((s)->_constVectorId)
+#define GetShaderDummyUniformCount(s)           ((s)->_dummyUniformCount)
+#define GetShaderTempRegCount(s)                ((s)->_tempRegCount)
+#define SetShaderTempRegCount(s, v)             ((s)->_tempRegCount = (v))
+#define GetShaderMaxLocalTempRegCount(s)        ((s)->_maxLocalTempRegCount)
+#define SetShaderMaxLocalTempRegCount(s, v)     ((s)->_maxLocalTempRegCount = (v))
+#define GetShaderEnableDefaultUBO(s)            ((s)->enableDefaultUBO)
+#define GetShaderDefaultUniformBlockIndex(s)    ((s)->_defaultUniformBlockIndex)
+#define GetShaderConstUniformBlockIndex(s)      ((s)->constUniformBlockIndex)
+#define GetShaderConstUBOSize(s)                ((s)->constUBOSize)
+#define GetShaderConstUBOData(s)                ((s)->constUBOData)
+#define GetShaderCompilerVersion(s)             ((s)->compilerVersion)
+#define GetShaderType(s)                        ((s)->type)
+#define GetShaderFlags(s)                       ((s)->flags)
+#define GetShaderMaxKernelFunctionArgs(s)       ((s)->maxKernelFunctionArgs)
+#define GetShaderGlobalUniformCount(s)          ((s)->globalUniformCount)
+#define GetShaderConstantMemorySize(s)          ((s)->constantMemorySize)
+#define GetShaderConstantMemoryBuffer(s)        ((s)->constantMemoryBuffer)
+#define GetShaderTypeNameBufferSize(s)          ((s)->typeNameBufferSize)
+#define GetShaderTypeNameBuffer(s)              ((s)->typeNameBuffer)
+#define GetShaderPrivateMemorySize(s)           ((s)->privateMemorySize)
+#define GetShaderLocalMemorySize(s)             ((s)->localMemorySize)
+#define GetShaderAttributeArraySize(s)          ((s)->attributeArraySize)
+#define GetShaderAttributeCount(s)              ((s)->attributeCount)
+#define GetShaderAttributes(s)                  ((s)->attributes)
+#define GetShaderAttribute(s, i)                ((s)->attributes[(i)])
+#define GetShaderUniformArraySize(s)            ((s)->uniformArraySize)
+#define GetShaderUniformCount(s)                ((s)->uniformCount)
+#define GetShaderUniformVectorCount(s)          ((s)->uniformVectorCount)
+#define GetShaderUniforms(s)                    ((s)->uniforms)
+#define GetShaderUniform(s, i)                  ((s)->uniforms[i])
+#define GetShaderSamplerIndex(s)                ((s)->samplerIndex)
+#define GetShaderUniformBlockArraySize(s)       ((s)->uniformBlockArraySize)
+#define GetShaderUniformBlockCount(s)           ((s)->uniformBlockCount)
+#define GetShaderUniformBlocks(s)               ((s)->uniformBlocks)
+#define GetShaderUniformBlock(s, i)             ((s)->uniformBlocks[(i)])
+#define GetShaderLocationArraySize(s)           ((s)->locationArraySize)
+#define GetShaderLocationCount(s)               ((s)->locationCount)
+#define GetShaderLocations(s)                   ((s)->locations)
+#define GetShaderOutputArraySize(s)             ((s)->outputArraySize)
+#define GetShaderOutputCount(s)                 ((s)->outputCount)
+#define GetShaderOutputs(s)                     ((s)->outputs)
+#define GetShaderVariableArraySize(s)           ((s)->variableArraySize)
+#define GetShaderVariableCount(s)               ((s)->variableCount)
+#define GetShaderVariables(s)                   ((s)->variables)
+#define GetShaderFunctionArraySize(s)           ((s)->functionArraySize)
+#define GetShaderFunctionCount(s)               ((s)->functionCount)
+#define GetShaderFunctions(s)                   ((s)->functions)
+#define GetShaderCurrentFunction(s)             ((s)->currentFunction)
+#define GetShaderKernelFunctionArraySize(s)     ((s)->kernelFunctionArraySize)
+#define GetShaderKernelFunctionCount(s)         ((s)->kernelFunctionCount)
+#define GetShaderKernelFunctions(s)             ((s)->kernelFunctions)
+#define GetShaderKernelFunction(s, i)           ((s)->kernelFunctions[(i)])
+#define GetShaderCurrentKernelFunction(s)       ((s)->currentKernelFunction)
+#define GetShaderWorkGroupSize(s)               ((s)->shaderLayout.compute.workGroupSize)
+#define SetShaderWorkGroupSize(s, v)            ((s)->shaderLayout.compute.workGroupSize[0] = (v)[0], \
+                                                 (s)->shaderLayout.compute.workGroupSize[1] = (v)[1], \
+                                                 (s)->shaderLayout.compute.workGroupSize[2] = (v)[2])
+#define GetShaderCodeCount(s)                   ((s)->codeCount)
+#define GetShaderLastInstruction(s)             ((s)->lastInstruction)
+#define GetShaderInstrIndex(s)                  ((s)->instrIndex)
+#define GetShaderLabels(s)                      ((s)->labels)
+#define GetShaderInstructions(s)                ((s)->code)
+#define GetShaderInstruction(s, i)              (&((s)->code[(i)]))
+#define GetShaderLoadUsers(s)                   ((s)->loadUsers)
+#define GetShaderLtcUniformCount(s)             ((s)->ltcUniformCount)
+#define GetShaderLtcUniformBegin(s)             ((s)->ltcUniformBegin)
+#define GetShaderLtcCodeUniformIndex(s, i)      (gcSHADER_GetLtcCodeUniformIndex((s), (i)))
+#define GetShaderLtcInstructionCount(s)         ((s)->ltcInstructionCount)
+#define GetShaderLtcExpressions(s)              ((s)->ltcExpressions)
+#define GetShaderLtcExpression(s, i)            (&((s)->ltcExpressions[(i)]))
+#define GetShaderVsPositionZDependsOnW(s)       ((s)->vsPositionZDependsOnW)
+#define GetShaderOptimizationOption(s)          ((s)->optimizationOption)
+#define GetShaderTransformFeedback(s)           ((s)->transformFeedback)
+#define GetShaderSourceLength(s)                ((s)->sourceLength)
+#define GetShaderSourceCode(s)                  ((s)->source)
+#define GetShaderMappingTableExntries(s)        ((s)->mappingTableExntries)
+#define GetShaderMappingTable(s)                ((s)->mappingTable)
+#define GetShaderLinkedToShaderId(s)            ((s)->linkedToShaderId)
+#define GetShaderLibraryList(s)                 ((s)->libraryList)
+#define GetShaderReplaceIndex(s)                ((s)->replaceIndex)
+#define GetShaderRARegWaterMark(s)              ((s)->RARegWaterMark)
+#define GetShaderRATempReg(s)                   ((s)->RATempReg)
+#define GetShaderRAHighestPass(s)               ((s)->RAHighestPriority)
+
+#define GetShaderHasIntrinsicBuiltin(s)         gcShaderHasIntrinsicBuiltin(s)
+#define SetShaderHasIntrinsicBuiltin(s, v)      do { \
+                                                   if((v) == gcvTRUE) { \
+                                                      gcShaderSetHasIntrinsicBuiltin(s); \
+                                                   } \
+                                                   else { \
+                                                      gcShaderClrHasIntrinsicBuiltin(s); \
+                                                   } \
+                                                } while (gcvFALSE)
+
+#define GetShaderHasExternFunction(s)           gcShaderHasExternFunction(s)
+#define SetShaderHasExternFunction(s, v)        do { \
+                                                   if((v) == gcvTRUE) { \
+                                                      gcShaderSetHasExternFunction(s); \
+                                                   } \
+                                                   else { \
+                                                      gcShaderClrHasExternFunction(s); \
+                                                   } \
+                                                } while (gcvFALSE)
+
+#define GetShaderHasExternVariable(s)           gcShaderHasExternVariable(s)
+#define SetShaderHasExternVariable(s, v)        do { \
+                                                   if((v) == gcvTRUE) { \
+                                                      gcShaderSetHasExternVariable(s); \
+                                                   } \
+                                                   else { \
+                                                      gcShaderClrHasExternVariable(s); \
+                                                   } \
+                                                } while (gcvFALSE)
+
+#define GetShaderNeedPatchForCentroid(s)        gcShaderNeedPatchForCentroid(s)
+#define SetShaderNeedPatchForCentroid(s, v)     do { \
+                                                   if((v) == gcvTRUE) { \
+                                                      gcShaderSetNeedPatchForCentroid(s); \
+                                                   } \
+                                                   else { \
+                                                      gcShaderClrNeedPatchForCentroid(s); \
+                                                   } \
+                                                } while (gcvFALSE)
+
+#define GetShaderOutputBlends(s)                ((s)->outputBlends)
+#define SetShaderOutputBlends(s, v)             ((s)->outputBlends |= (v))
+#define ResetShaderOutputBlends(s, v)           ((s)->outputBlends &= ~(v))
+#define ClearShaderOutputBlends(s)              ((s)->outputBlends = gcvLAYOUT_QUALIFIER_NONE)
+
+#define SetComputeShaderLayout(s, ws_x, ws_y, ws_z)                         \
+        do {                                                                \
+             gcmASSERT(GetShaderType(s) == gcSHADER_TYPE_COMPUTE);          \
+             (s)->shaderLayout.compute.workGroupSize[0] = (ws_x);           \
+             (s)->shaderLayout.compute.workGroupSize[1] = (ws_y);           \
+             (s)->shaderLayout.compute.workGroupSize[2] = (ws_z);           \
+        } while(0)
+
+#define SetTcsShaderLayout(s, outVertices, inVertices)                      \
+        do {                                                                \
+             gcmASSERT(GetShaderType(s) == gcSHADER_TYPE_TCS);              \
+             (s)->shaderLayout.tcs.tcsPatchOutputVertices = (outVertices);  \
+             (s)->shaderLayout.tcs.tcsInputVerticesUniform = (inVertices);  \
+        } while(0)
+
+#define SetTesShaderLayout(s, pMode, vSpacing, order, pointMode, inVertices)                    \
+        do {                                                                                    \
+             gcmASSERT(GetShaderType(s) == gcSHADER_TYPE_TES);                                  \
+             (s)->shaderLayout.tes.tessPrimitiveMode      = (gcTessPrimitiveMode)(pMode);       \
+             (s)->shaderLayout.tes.tessVertexSpacing      = (gcTessVertexSpacing)(vSpacing);    \
+             (s)->shaderLayout.tes.tessOrdering           = (gcTessOrdering)(order);            \
+             (s)->shaderLayout.tes.tessPointMode          = (pointMode);                        \
+             (s)->shaderLayout.tes.tessPatchInputVertices = (inVertices);                       \
+        } while(0)
+
+#define SetGeoShaderLayout(s, invoc, maxVertices, inPrimitive, outPrimitive)\
+        do {                                                                \
+             gcmASSERT(GetShaderType(s) == gcSHADER_TYPE_GEOMETRY);         \
+             (s)->shaderLayout.geo.geoInvocations = (invoc);                \
+             (s)->shaderLayout.geo.geoMaxVertices = (maxVertices);          \
+             (s)->shaderLayout.geo.geoInPrimitive = (inPrimitive);          \
+             (s)->shaderLayout.geo.geoOutPrimitive = (outPrimitive);        \
+        } while(0)
+
+typedef enum _gcBuiltinConst
+{
+    gcBIConst_MaxVertexAttribs = 0,
+    gcBIConst_MaxVertexUniformVectors,
+    gcBIConst_MaxVertexOutputVectors,
+    gcBIConst_MaxFragmentInputVectors,
+    gcBIConst_MaxVertexTextureImageUnits,
+    gcBIConst_MaxCombinedTextureImageUnits,
+    gcBIConst_MaxTextureImageUnits,
+    gcBIConst_MaxFragmentUniformVectors,
+    gcBIConst_MaxDrawBuffers,
+    gcBIConst_MaxSamples,
+    gcBIConst_MinProgramTexelOffset,
+    gcBIConst_MaxProgramTexelOffset,
+    gcBIConst_MaxImageUnits,
+    gcBIConst_MaxVertexImageUniforms,
+    gcBIConst_MaxFragmentImageUniforms,
+    gcBIConst_MaxComputeImageUniforms,
+    gcBIConst_MaxCombinedImageUniforms,
+    gcBIConst_MaxCombinedShaderOutputResources,
+    gcBIConst_MaxComputeWorkGroupCount,
+    gcBIConst_MaxComputeWorkGroupSize,
+    gcBIConst_MaxComputeUniformComponents,
+    gcBIConst_MaxComputeTextureImageUnits,
+    gcBIConst_MaxComputeAtomicCounters,
+    gcBIConst_MaxComputeAtomicCounterBuffers,
+    gcBIConst_MaxVertexAtomicCounters,
+    gcBIConst_MaxFragmentAtomicCounters,
+    gcBIConst_MaxCombinedAtomicCounters,
+    gcBIConst_MaxAtomicCounterBindings,
+    gcBIConst_MaxVertexAtomicCounterBuffers,
+    gcBIConst_MaxFragmentAtomicCounterBuffers,
+    gcBIConst_MaxCombinedAtomicCounterBuffers,
+    gcBIConst_MaxAtomicCounterBufferSize,
+    /* ES 1.0 */
+    gcBIConst_MaxVaryingVectors,
+    /* TS EXT */
+    gcBIConst_MaxTessControlInputComponents,
+    gcBIConst_MaxTessControlOutputComponents,
+    gcBIConst_MaxTessControlTextureImageUnits,
+    gcBIConst_MaxTessControlImageUniforms,
+    gcBIConst_MaxTessControlUniformComponents,
+    gcBIConst_MaxTessControlTotalOutputComponents,
+    gcBIConst_MaxTessControlAtomicCounters,
+    gcBIConst_MaxTessControlAtomicCounterBuffers,
+    gcBIConst_MaxTessEvaluationInputComponents,
+    gcBIConst_MaxTessEvaluationOutputComponents,
+    gcBIConst_MaxTessEvaluationTextureImageUnits,
+    gcBIConst_MaxTessEvaluationImageUniforms,
+    gcBIConst_MaxTessEvaluationUniformComponents,
+    gcBIConst_MaxTessEvaluationAtomicCounters,
+    gcBIConst_MaxTessEvaluationAtomicCounterBuffers,
+    gcBIConst_MaxTessPatchComponents,
+    gcBIConst_MaxPatchVertices,
+    gcBIConst_MaxTessGenLevel,
+    /* GS EXT */
+    gcBIConst_MaxGSInputComponents,
+    gcBIConst_MaxGSOutputComponents,
+    gcBIConst_MaxGSImageUniforms,
+    gcBIConst_MaxGSTextureImageUnits,
+    gcBIConst_MaxGSOutputVertices,
+    gcBIConst_MaxGSTotalOutputComponents,
+    gcBIConst_MaxGSUniformComponents,
+    gcBIConst_MaxGSAtomicCounters,
+    gcBIConst_MaxGSAtomicCounterBuffers,
+
+    /* Desktop GL */
+    gcBIConst_MaxClipDistances,
+    gcBIConst_MaxClipPlanes,
+    gcBIConst_MaxFragmentUniformComponents,
+    gcBIConst_MaxTextureCoords,
+    gcBIConst_MaxTextureUnits,
+    gcBIConst_MaxVaryingComponents,
+    gcBIConst_MaxVaryingFloats,
+    gcBIConst_MaxVertexUniformComponents,
+    gcBIConst_MaxFragmentInputComponents,
+    gcBIConst_MaxVertexOutputComponents,
+    gcBIConst_MaxGSVaryingComponents,
+
+    /* Constant count */
+    gcBIConst_Count
+} gcBuiltinConst;
+
+END_EXTERN_C()
+
+#endif /* __gc_vsc_old_gcsl_h_ */
+
+
index d5673b8ae06f4cce957f83a1da2df5c3589d4fc5..3b5fa4d408e4ef9fe3d493350dc29b27d5ee51f4 100644 (file)
@@ -16,18 +16,28 @@ include $(LOCAL_PATH)/../../Android.mk.def
 
 ifeq ($(VIVANTE_ENABLE_VSIMULATOR),0)
 
+
 #
 # galcore.ko
 #
 include $(CLEAR_VARS)
-.PHONY: KBUILD
 
+GALCORE_OUT := $(TARGET_OUT_INTERMEDIATES)/GALCORE_OBJ
 GALCORE := \
-       $(LOCAL_PATH)/../../galcore.ko
+       $(GALCORE_OUT)/galcore.ko
+
+KERNELENVSH := $(GALCORE_OUT)/kernelenv.sh
+$(KERNELENVSH):
+       rm -rf $(KERNELENVSH)
+       echo 'export KERNEL_DIR=$(KERNEL_DIR)' > $(KERNELENVSH)
+       echo 'export CROSS_COMPILE=$(CROSS_COMPILE)' >> $(KERNELENVSH)
+       echo 'export ARCH_TYPE=$(ARCH_TYPE)' >> $(KERNELENVSH)
 
-$(GALCORE):   KBUILD
+GALCORE_LOCAL_PATH := $(LOCAL_PATH)
+
+$(GALCORE): $(KERNELENVSH)
        @cd $(AQROOT)
-       @$(MAKE) -f Kbuild -C $(AQROOT) \
+       source $(KERNELENVSH); $(MAKE) -f Kbuild -C $(AQROOT) \
                AQROOT=$(abspath $(AQROOT)) \
                AQARCH=$(abspath $(AQARCH)) \
                AQVGARCH=$(abspath $(AQVGARCH)) \
@@ -36,10 +46,11 @@ $(GALCORE):   KBUILD
                VIVANTE_ENABLE_DRM=$(DRM_GRALLOC) \
                VIVANTE_ENABLE_2D=$(VIVANTE_ENABLE_2D) \
                VIVANTE_ENABLE_3D=$(VIVANTE_ENABLE_3D) \
-               VIVANTE_ENABLE_VG=$(VIVANTE_ENABLE_VG)
+               VIVANTE_ENABLE_VG=$(VIVANTE_ENABLE_VG); \
+               cp $(GALCORE_LOCAL_PATH)/../../galcore.ko $(GALCORE)
 
-LOCAL_SRC_FILES := \
-       ../../galcore.ko
+LOCAL_PREBUILT_MODULE_FILE := \
+       $(GALCORE)
 
 LOCAL_GENERATED_SOURCES := \
        $(AQREG) \
@@ -99,6 +110,10 @@ LOCAL_MODULE_TAGS    := optional
 
 LOCAL_PRELINK_MODULE := false
 
+ifeq ($(PLATFORM_VENDOR),1)
+LOCAL_VENDOR_MODULE  := true
+endif
 include $(BUILD_STATIC_LIBRARY)
 
 endif
+
index 5ca7cea2761513c755c4f88fe5f813383802c144..17494703e851d1ee410eeb12dac2c154aaf4529a 100644 (file)
         gcvFALSE, gcvFALSE                                                     \
         )
 
+#define _STATE_INIT_VALUE_BLOCK(reg, value, block, count)                      \
+    _State(\
+        Context, index, \
+        (reg ## _Address >> 2) + (block << reg ## _BLK), \
+        value, \
+        count, \
+        gcvFALSE, gcvFALSE                                                     \
+        )
+
+
 #define _CLOSE_RANGE()                                                         \
     _TerminateStateBlock(Context, index)
 
@@ -223,6 +233,8 @@ _FlushPipe(
     gctBOOL halti5;
     gctBOOL snapPages;
     gctBOOL hwTFB;
+    gctBOOL blt;
+    gctBOOL peTSFlush;
     gctBOOL multiCluster;
 
     txCacheFix
@@ -244,17 +256,22 @@ _FlushPipe(
     hwTFB
         = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_HW_TFB);
 
+    blt
+        = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_BLT_ENGINE);
     multiCluster
         = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_MULTI_CLUSTER);
 
-    flushSlots = 6;
+    peTSFlush
+        = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX);
+
+    flushSlots = blt ? 10 : 6;
 
     if (Pipe == gcvPIPE_3D)
     {
         if (!txCacheFix)
         {
             /* Semaphore stall */
-            flushSlots += 4;
+            flushSlots += blt ? 8 : 4;
         }
 
         /* VST cache */
@@ -264,12 +281,12 @@ _FlushPipe(
     if (fcFlushStall)
     {
         /* Flush tile status cache. */
-        flushSlots += 6;
+        flushSlots += blt ? ((!peTSFlush) ? 14 :10) : 6;
     }
 
     if (iCacheInvalidate && !halti5)
     {
-        flushSlots += 12;
+        flushSlots += blt ? 16 : 12;
     }
 
     if (hwTFB)
@@ -292,9 +309,11 @@ _FlushPipe(
 
         if (Pipe == gcvPIPE_3D && !txCacheFix)
         {
-            /* Semaphore from FE to PE. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (blt)
+            {
+                /* Semaphore from FE to BLT. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -304,7 +323,7 @@ _FlushPipe(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -314,7 +333,51 @@ _FlushPipe(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -325,8 +388,8 @@ _FlushPipe(
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -336,7 +399,143 @@ _FlushPipe(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                /* Stall from FE to BLT. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+            }
+            else
+            {
+                /* Semaphore from FE to PE. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -347,9 +546,9 @@ _FlushPipe(
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
-            /* Stall from FE to PE. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                /* Stall from FE to PE. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -360,8 +559,8 @@ _FlushPipe(
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -371,7 +570,7 @@ _FlushPipe(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -381,6 +580,7 @@ _FlushPipe(
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
         }
 
         /* Flush the current pipe. */
@@ -526,7 +726,7 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
              *buffer++
-                 = 0x12345678;
+                 = 0x1;
         }
 
         /* Flush VST in separate cmd. */
@@ -577,8 +777,11 @@ _FlushPipe(
         }
 
         /* Semaphore from FE to PE. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        if (blt)
+        {
+            /* Semaphore from FE to BLT. */
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -588,7 +791,7 @@ _FlushPipe(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -598,56 +801,65 @@ _FlushPipe(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
12:8) - (0 ?
12:8) + 1))))))) << (0 ?
12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
12:8) - (0 ?
12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
0:0) - (0 ?
0:0) + 1))))))) << (0 ?
0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
0:0) - (0 ?
0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
 
-        /* Stall from FE to PE. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  4:0) - (0 ?
  4:0) + 1))))))) << (0 ?
@@ -655,19 +867,18 @@ _FlushPipe(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  12:8) - (0 ?
  12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
-        if (fcFlushStall)
-        {
+            /* Stall from FE to BLT. */
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
@@ -675,20 +886,44 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
                 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
                 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
@@ -698,7 +933,17 @@ _FlushPipe(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -707,12 +952,13 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ?
  0:0) - (0 ?
  0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
-
-            /* Semaphore from FE to PE. */
+        }
+        else
+        {
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
@@ -803,11 +1049,12 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
         }
 
-        if (iCacheInvalidate && !halti5)
+        if (fcFlushStall)
         {
-            /* Invalidate I$ after pipe is stalled */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (!peTSFlush && blt)
+            {
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -817,7 +1064,7 @@ _FlushPipe(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -827,31 +1074,31 @@ _FlushPipe(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  0:0) - (0 ?
  0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -861,7 +1108,51 @@ _FlushPipe(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -871,41 +1162,82 @@ _FlushPipe(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  0:0) - (0 ?
  0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+            }
+            else
+            {
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 4:4) - (0 ?
- 4:4) + 1))))))) << (0 ?
- 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+            }
+
+            /* Semaphore from FE to PE. */
+            if (blt)
+            {
+                /* Semaphore from FE to BLT. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -915,7 +1247,7 @@ _FlushPipe(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -925,29 +1257,820 @@ _FlushPipe(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                /* Stall from FE to BLT. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+            }
+            else
+            {
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                /* Stall from FE to PE. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
+        }
+
+        if (iCacheInvalidate && !halti5)
+        {
+            /* Invalidate I$ after pipe is stalled */
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+
+            /* Semaphore from FE to PE. */
+            if (blt)
+            {
+                /* Semaphore from FE to BLT. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                /* Stall from FE to BLT. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+            }
+            else
+            {
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                /* Stall from FE to PE. */
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
+        }
+
+        if (snapPages)
+        {
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x13 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x04 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
                 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
15:0) - (0 ?
15:0) + 1) == 32) ?
4:0) - (0 ?
4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
15:0) - (0 ?
15:0) + 1))))))) << (0 ?
15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ?
15:0) - (0 ?
15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
4:0) - (0 ?
4:0) + 1))))))) << (0 ?
4:0))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
4:0) - (0 ?
4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
 
             *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+                = 0;
+        }
+    }
+
+    /* Number of slots taken by flushing pipe. */
+    return flushSlots;
+}
+#endif
+
+#if gcdENABLE_3D
+static gctUINT32
+_SemaphoreStall(
+    IN gckCONTEXT Context,
+    IN gctUINT32 Index
+    )
+{
+    gctBOOL blt = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_BLT_ENGINE);
+    if (Context->buffer != gcvNULL)
+    {
+        gctUINT32_PTR buffer;
+
+        /* Address correct index. */
+        buffer = Context->buffer->logical + Index;
 
+        if (blt)
+        {
+            /* Semaphore from FE to BLT. */
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
@@ -975,7 +2098,7 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
@@ -990,19 +2113,8 @@ _FlushPipe(
  0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 5:5) - (0 ?
- 5:5) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 5:5) - (0 ?
- 5:5) + 1))))))) << (0 ?
- 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 5:5) - (0 ?
- 5:5) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
 
-            /* Semaphore from FE to PE. */
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
@@ -1052,12 +2164,12 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ?
  12:8) - (0 ?
  12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
-            /* Stall from FE to PE. */
+            /* Stall from FE to BLT. */
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
@@ -1087,14 +2199,11 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ?
  12:8) - (0 ?
  12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-        }
 
-        if (snapPages)
-        {
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
@@ -1102,88 +2211,48 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x13 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
                 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x04 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
4:0) - (0 ?
4:0) + 1))))))) << (0 ?
4:0))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
4:0) - (0 ?
4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
25:16) - (0 ?
25:16) + 1))))))) << (0 ?
25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
25:16) - (0 ?
25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
                 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
4:0) - (0 ?
4:0) + 1) == 32) ?
15:0) - (0 ?
15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
4:0) - (0 ?
4:0) + 1))))))) << (0 ?
4:0))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
4:0) - (0 ?
4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
15:0) - (0 ?
15:0) + 1))))))) << (0 ?
15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
15:0) - (0 ?
15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-            *buffer++
-                = 0;
+            *buffer
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
         }
-    }
-
-    /* Number of slots taken by flushing pipe. */
-    return flushSlots;
-}
-#endif
-
-#if gcdENABLE_3D
-static gctUINT32
-_SemaphoreStall(
-    IN gckCONTEXT Context,
-    IN gctUINT32 Index
-    )
-{
-    if (Context->buffer != gcvNULL)
-    {
-        gctUINT32_PTR buffer;
-
-        /* Address correct index. */
-        buffer = Context->buffer->logical + Index;
-
-        /* Semaphore from FE to PE. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        else
+        {
+            /* Semaphore from FE to PE. */
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1193,7 +2262,7 @@ _SemaphoreStall(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1203,7 +2272,7 @@ _SemaphoreStall(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1214,8 +2283,8 @@ _SemaphoreStall(
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1225,7 +2294,7 @@ _SemaphoreStall(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1236,9 +2305,9 @@ _SemaphoreStall(
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
-        /* Stall from FE to PE. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            /* Stall from FE to PE. */
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1249,8 +2318,8 @@ _SemaphoreStall(
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
-        *buffer
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1260,7 +2329,7 @@ _SemaphoreStall(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -1270,10 +2339,11 @@ _SemaphoreStall(
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+        }
     }
 
     /* Semaphore/stall takes 4 slots. */
-    return 4;
+    return (blt ? 8 : 4);
 }
 #endif
 
@@ -1486,14 +2556,6 @@ _State(
 
                 /* Set index in state mapping table. */
                 Context->map[Address + i].index = (gctUINT)Index + 1 + i;
-
-#if gcdSECURE_USER
-                /* Save hint. */
-                if (Context->hint != gcvNULL)
-                {
-                    Context->hint[Address + i] = Hinted;
-                }
-#endif
             }
         }
 
@@ -1531,14 +2593,6 @@ _State(
 
             /* Set index in state mapping table. */
             Context->map[Address + i].index = (gctUINT)Index + i;
-
-#if gcdSECURE_USER
-            /* Save hint. */
-            if (Context->hint != gcvNULL)
-            {
-                Context->hint[Address + i] = Hinted;
-            }
-#endif
         }
     }
 
@@ -1569,11 +2623,6 @@ _StateMirror(
             /* Copy the mapping address. */
             Context->map[Address + i].index =
                 Context->map[AddressMirror + i].index;
-
-#if gcdSECURE_USER
-            Context->hint[Address + i] =
-                Context->hint[AddressMirror + i];
-#endif
         }
     }
 
@@ -1808,7 +2857,7 @@ _InitializeContextBuffer(
 #if gcdENABLE_3D
     gctBOOL halti0, halti1, halti2, halti3, halti4, halti5;
     gctUINT i;
-    gctUINT vertexUniforms, fragmentUniforms, vsConstBase, psConstBase, constMax;
+    gctUINT vertexUniforms, fragmentUniforms;
     gctBOOL unifiedUniform;
     gctBOOL hasGS, hasTS;
     gctBOOL genericAttrib;
@@ -1824,6 +2873,8 @@ _InitializeContextBuffer(
     gctBOOL multiCoreBlockSetCfg2;
     gctUINT clusterAliveMask;
     gctBOOL hasPSCSThrottle;
+    gctBOOL hasMsaaFragOperation;
+    gctBOOL newGPipe;
 #endif
 
     gckHARDWARE hardware;
@@ -1873,6 +2924,8 @@ _InitializeContextBuffer(
     multiCoreBlockSetCfg2 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MULTI_CORE_BLOCK_SET_CONFIG2);
     clusterAliveMask = hardware->identity.clusterAvailMask & hardware->options.userClusterMask;
     hasPSCSThrottle = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_PSCS_THROTTLE);
+    hasMsaaFragOperation = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MSAA_FRAGMENT_OPERATION);
+    newGPipe = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_NEW_GPIPE);
 
     /* Multi render target. */
     if (Context->hardware->identity.chipModel == gcv880 &&
@@ -1902,39 +2955,14 @@ _InitializeContextBuffer(
     }
 
     /* Query how many uniforms can support. */
-    {if (Context->hardware->identity.numConstants > 256){    unifiedUniform = gcvTRUE;
-if (smallBatch){    vsConstBase  = 0xD000;
-    psConstBase  = 0xD000;
-}else if (halti5){    vsConstBase  = 0xD000;
-    psConstBase  = 0xD800;
-}else{    vsConstBase  = 0xC000;
-    psConstBase  = 0xC000;
-}if ((Context->hardware->identity.chipModel == gcv880) && ((Context->hardware->identity.chipRevision & 0xfff0) == 0x5120)){    vertexUniforms   = 512;
-    fragmentUniforms   = 64;
-    constMax     = 576;
-}else{    vertexUniforms   = gcmMIN(512, Context->hardware->identity.numConstants - 64);
-    fragmentUniforms   = gcmMIN(512, Context->hardware->identity.numConstants - 64);
-    constMax     = Context->hardware->identity.numConstants;
-}}else if (Context->hardware->identity.numConstants == 256){    if (Context->hardware->identity.chipModel == gcv2000 && (Context->hardware->identity.chipRevision == 0x5118 || Context->hardware->identity.chipRevision == 0x5140))    {        unifiedUniform = gcvFALSE;
-        vsConstBase  = 0x1400;
-        psConstBase  = 0x1C00;
-        vertexUniforms   = 256;
-        fragmentUniforms   = 64;
-        constMax     = 320;
-    }    else    {        unifiedUniform = gcvFALSE;
-        vsConstBase  = 0x1400;
-        psConstBase  = 0x1C00;
-        vertexUniforms   = 256;
-        fragmentUniforms   = 256;
-        constMax     = 512;
-    }}else{    unifiedUniform = gcvFALSE;
-    vsConstBase  = 0x1400;
-    psConstBase  = 0x1C00;
-    vertexUniforms   = 168;
-    fragmentUniforms   = 64;
-    constMax     = 232;
-}};
-
+    gcmCONFIGUREUNIFORMS2(Context->hardware->identity.chipModel,
+                         Context->hardware->identity.chipRevision,
+                         halti5,
+                         smallBatch,
+                         Context->hardware->identity.numConstants,
+                         unifiedUniform,
+                         vertexUniforms,
+                         fragmentUniforms);
 
 #if !gcdENABLE_UNIFIED_CONSTANT
     if (Context->hardware->identity.numConstants > 256)
@@ -1955,7 +2983,7 @@ if (smallBatch){    vsConstBase  = 0xD000;
 
     if (multiCluster)
     {
-        index += _State(Context, index, 0x03910 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        index += _State(Context, index, (0x03910 >> 2) + (0 << 2), ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  7:0) - (0 ?
  7:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -2065,7 +3093,7 @@ if (smallBatch){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x007D0 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
         index += _State(Context, index, 0x007D8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
         index += _State(Context, index, 0x17A80 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
-        if (genericAttrib)
+        if (genericAttrib || newGPipe)
         {
             index += _State(Context, index, 0x17880 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
             index += _State(Context, index, 0x17900 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
@@ -2450,9 +3478,10 @@ if (smallBatch){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x01038 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     }
 
-    if (halti4)
+    if (hasMsaaFragOperation)
     {
         index += _State(Context, index, 0x01054 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x01060 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
     }
 
     if (halti5)
@@ -3092,12 +4121,6 @@ if (smallBatch){    vsConstBase  = 0xD000;
 
     Context->totalSize = index * gcmSIZEOF(gctUINT32);
 
-#if gcdENABLE_3D
-    psConstBase = psConstBase;
-    vsConstBase = vsConstBase;
-    constMax = constMax;
-#endif
-
     /* Success. */
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -3177,14 +4200,6 @@ _DestroyContext(
             Context->buffer = next;
         }
 
-#if gcdSECURE_USER
-        /* Free the hint array. */
-        if (Context->hint != gcvNULL)
-        {
-            gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
-        }
-#endif
-
         /* Mark the gckCONTEXT object as unknown. */
         Context->object.type = gcvOBJ_UNKNOWN;
 
@@ -3372,20 +4387,6 @@ gckCONTEXT_Construct(
         {
             context->map = context->hardware->kernel->command->stateMap;
         }
-
-        /**************************************************************************/
-        /* Allocate the hint array. ***********************************************/
-
-#if gcdSECURE_USER
-        /* Allocate hints. */
-        gcmkONERROR(gckOS_Allocate(
-            Os,
-            gcmSIZEOF(gctBOOL) * context->maxState,
-            &pointer
-            ));
-
-        context->hint = pointer;
-#endif
     }
 
     /**************************************************************************/
@@ -3630,10 +4631,6 @@ gckCONTEXT_Update(
     gctUINT i, j;
     gctUINT32 dirtyRecordArraySize = 0;
 
-#if gcdSECURE_USER
-    gcskSECURE_CACHE_PTR cache;
-#endif
-
     gcmkHEADER_ARG(
         "Context=%p ProcessID=%d StateDelta=%p",
         Context, ProcessID, StateDelta
@@ -3657,11 +4654,6 @@ gckCONTEXT_Update(
         Context->os, buffer->signal, gcvFALSE, gcvINFINITE
         ));
 
-#if gcdSECURE_USER
-    /* Get the cache form the database. */
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
-#endif
-
 #if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && gcdENABLE_3D
     /* Update current context token. */
     buffer->logical[Context->map[0x0E14].index]
@@ -3703,58 +4695,62 @@ gckCONTEXT_Update(
                     dirtyRecordArraySize,
                     (gctPOINTER *) &recordArray
                     ));
-            }
 
-            /* Merge all pending states. */
-            for (j = 0; j < kDelta->recordCount; j += 1)
-            {
-                if (j >= Context->numStates)
+                if (recordArray == gcvNULL)
                 {
-                    break;
+                    gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
                 }
 
-                /* Get the current state record. */
-                record = &recordArray[j];
+                /* Merge all pending states. */
+                for (j = 0; j < kDelta->recordCount; j += 1)
+                {
+                    if (j >= Context->numStates)
+                    {
+                        break;
+                    }
 
-                /* Get the state address. */
-                gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->address, &address));
+                    /* Get the current state record. */
+                    record = &recordArray[j];
 
-                /* Make sure the state is a part of the mapping table. */
-                if (address >= Context->maxState)
-                {
-                    gcmkTRACE(
-                        gcvLEVEL_ERROR,
-                        "%s(%d): State 0x%04X (0x%04X) is not mapped.\n",
-                        __FUNCTION__, __LINE__,
-                        address, address << 2
-                        );
-
-                    continue;
-                }
+                    /* Get the state address. */
+                    gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->address, &address));
 
-                /* Get the state index. */
-                index = map[address].index;
+                    /* Make sure the state is a part of the mapping table. */
+                    if (address >= Context->maxState)
+                    {
+                        gcmkTRACE(
+                            gcvLEVEL_ERROR,
+                            "%s(%d): State 0x%04X (0x%04X) is not mapped.\n",
+                            __FUNCTION__, __LINE__,
+                            address, address << 2
+                            );
+
+                        continue;
+                    }
 
-                /* Skip the state if not mapped. */
-                if (index == 0)
-                {
-                    continue;
-                }
+                    /* Get the state index. */
+                    index = map[address].index;
 
-                /* Get the data mask. */
-                gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->mask, &mask));
+                    /* Skip the state if not mapped. */
+                    if (index == 0)
+                    {
+                        continue;
+                    }
 
-                /* Get the new data value. */
-                gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->data, &data));
+                    /* Get the data mask. */
+                    gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->mask, &mask));
 
-                /* Masked states that are being completly reset or regular states. */
-                if ((mask == 0) || (mask == ~0U))
-                {
-                    /* Process special states. */
-                    if (address == 0x0595)
+                    /* Get the new data value. */
+                    gcmkONERROR(gckOS_ReadMappedPointer(kernel->os, &record->data, &data));
+
+                    /* Masked states that are being completly reset or regular states. */
+                    if ((mask == 0) || (mask == ~0U))
                     {
-                        /* Force auto-disable to be disabled. */
-                        data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        /* Process special states. */
+                        if (address == 0x0595)
+                        {
+                            /* Force auto-disable to be disabled. */
+                            data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  5:5) - (0 ?
  5:5) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -3764,7 +4760,7 @@ gckCONTEXT_Update(
  5:5) - (0 ?
  5:5) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
-                        data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                            data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:4) - (0 ?
  4:4) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -3774,7 +4770,7 @@ gckCONTEXT_Update(
  4:4) - (0 ?
  4:4) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
-                        data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                            data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  13:13) - (0 ?
  13:13) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -3784,29 +4780,19 @@ gckCONTEXT_Update(
  13:13) - (0 ?
  13:13) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13)));
+                        }
+
+                        /* Set new data. */
+                        buffer->logical[index] = data;
                     }
 
-#if gcdSECURE_USER
-                    /* Do we need to convert the logical address? */
-                    if (Context->hint[address])
+                    /* Masked states that are being set partially. */
+                    else
                     {
-                        /* Map handle into physical address. */
-                        gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
-                            kernel, cache, (gctPOINTER) &data
-                            ));
+                        buffer->logical[index]
+                            = (~mask & buffer->logical[index])
+                            | (mask & data);
                     }
-#endif
-
-                    /* Set new data. */
-                    buffer->logical[index] = data;
-                }
-
-                /* Masked states that are being set partially. */
-                else
-                {
-                    buffer->logical[index]
-                        = (~mask & buffer->logical[index])
-                        | (mask & data);
                 }
             }
 
index 29f394de49ed77592008131c3682c5f4867201d4..11d94d71f0fd6ec23d556e4cfaf90bb8abce4c4c 100644 (file)
@@ -173,11 +173,6 @@ struct _gckCONTEXT
 
     gctUINT32                   pipeSelectBytes;
 
-    /* Hint array. */
-#if gcdSECURE_USER
-    gctBOOL_PTR                 hint;
-#endif
-
     gcsPROFILER_COUNTERS_PART1    latestProfiler_part1;
     gcsPROFILER_COUNTERS_PART1    histroyProfiler_part1;
     gcsPROFILER_COUNTERS_PART1    preProfiler_part1;
index 22c58c65975bd849f6ff7048298a35e1b09e58f1..998621ef0ee9c3ec022dd3274548b406abbd5182 100644 (file)
@@ -270,7 +270,7 @@ _IdentifyHardwareByDatabase(
                                 0x00030,
                                 &Identity->customerID));
 
-    /*get hw minor features*/
+     /*get hw minor features*/
     gcmkONERROR(
         gckOS_ReadRegisterEx(Os, Core,
                                 0x0001C,
@@ -340,19 +340,17 @@ _IdentifyHardwareByDatabase(
     Identity->streamCount                   = database->Streams;
     Identity->clusterAvailMask              = database->ClusterAliveMask;
 
-    gckOS_QueryOption(Hardware->os, "sRAMMode", (gctUINT64 *)&Hardware->sRAMNonExclusive);
-
     if (gcmIS_SUCCESS(gckOS_QueryOption(Hardware->os, "sRAMBases", Device->sRAMBases[0])))
     {
         gckOS_MemCopy(
             Identity->sRAMBases,
             Device->sRAMBases[Core],
-            sizeof(gctUINT64) * gcvSRAM_COUNT
+            sizeof(gctUINT64) * gcvSRAM_INTER_COUNT
             );
     }
     else
     {
-        for (i = 0; i < gcvSRAM_COUNT; i++)
+        for (i = 0; i < gcvSRAM_INTER_COUNT; i++)
         {
             Identity->sRAMBases[i] = gcvINVALID_PHYSICAL_ADDRESS;
         }
@@ -363,11 +361,11 @@ _IdentifyHardwareByDatabase(
         gckOS_MemCopy(
             Identity->sRAMSizes,
             Device->sRAMSizes[Core],
-            sizeof(gctUINT32) * gcvSRAM_COUNT
+            sizeof(gctUINT32) * gcvSRAM_INTER_COUNT
             );
     }
 
-    for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_COUNT; i++)
+    for (i = gcvSRAM_INTERNAL0; i < gcvSRAM_INTER_COUNT; i++)
     {
         if (Identity->sRAMSizes[i])
         {
@@ -375,16 +373,36 @@ _IdentifyHardwareByDatabase(
         }
     }
 
-    /* If module parameter doesn't set SRAM sizes. */
-    if (i == gcvSRAM_COUNT)
+    /* If module parameter doesn't set per-core SRAM sizes. */
+    if (i == gcvSRAM_INTER_COUNT)
+    {
+        for (i = gcvSRAM_INTERNAL0; i < gcvSRAM_INTER_COUNT; i++)
+        {
+            /* Try to get SRAM sizes from database. */
+            Device->sRAMSizes[Core][i] = Identity->sRAMSizes[i] = database->VIP_SRAM_SIZE;
+        }
+    }
+
+    gckOS_QueryOption(Hardware->os, "extSRAMBases", Device->extSRAMBases);
+
+    gckOS_QueryOption(Hardware->os, "extSRAMSizes", (gctUINT64 *)Device->extSRAMSizes);
+
+    for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_EXT_COUNT; i++)
     {
-        /* Set default mode to exclusive mode. */
-        Hardware->sRAMNonExclusive = gcvFALSE;
+        if (Device->extSRAMSizes[i])
+        {
+            break;
+        }
+    }
 
-        /* Try to get SRAM sizes from database. */
-        /* Need this path for VIP exclusive mode. */
-        Device->sRAMSizes[Core][gcvSRAM_INTERNAL] = Identity->sRAMSizes[gcvSRAM_INTERNAL] = database->VIP_SRAM_SIZE;
-        Device->sRAMSizes[Core][gcvSRAM_EXTERNAL0] = Identity->sRAMSizes[gcvSRAM_EXTERNAL0] = database->AXI_SRAM_SIZE;
+    /* If module parameter doesn't set external SRAM sizes. */
+    if (i == gcvSRAM_EXT_COUNT)
+    {
+        for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_EXT_COUNT; i++)
+        {
+            /* Try to get SRAM sizes from database. */
+            Device->extSRAMSizes[i] = database->AXI_SRAM_SIZE;
+        }
     }
 
     if (Identity->chipModel == gcv320)
@@ -434,6 +452,8 @@ _IdentifyHardwareByDatabase(
         Identity->chipFlags |= gcvCHIP_AXI_BUS128_BITS;
     }
 
+    gckOS_QueryOption(Os, "platformFlagBits", &Identity->platformFlagBits);
+
     /* Success. */
     gcmkFOOTER();
     return gcvSTATUS_OK;
@@ -853,7 +873,6 @@ _ConfigureModuleLevelClockGating(
 }
 #endif
 
-#if gcdPOWER_MANAGEMENT_REFINEMENT
 static void
 _PowerStateTimerFunc(
     gctPOINTER Data
@@ -861,22 +880,8 @@ _PowerStateTimerFunc(
 {
     gckHARDWARE hardware = (gckHARDWARE)Data;
 
-    gckHARDWARE_SetPowerManagementState(hardware,
-                                        hardware->nextPowerState);
+    gcmkVERIFY_OK(gckHARDWARE_SetPowerState(hardware, hardware->nextPowerState));
 }
-#else
-#if gcdPOWEROFF_TIMEOUT
-void
-_PowerTimerFunction(
-    gctPOINTER Data
-    )
-{
-    gckHARDWARE hardware = (gckHARDWARE)Data;
-    gcmkVERIFY_OK(
-        gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
-}
-#endif
-#endif
 
 static gceSTATUS
 _VerifyDMA(
@@ -1065,7 +1070,7 @@ _DumpFEStack(
 
     for (i = 0; i < gcmCOUNTOF(_feStacks); i++)
     {
-        gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].clear);
+        gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].clear));
 
         for (j = 0; j < _feStacks[i].count; j++)
         {
@@ -1496,6 +1501,12 @@ _QueryFeatureDatabase(
 
     case gcvFEATURE_FE_NEED_DUMMYDRAW:
         available = database->FE_NEED_DUMMYDRAW;
+
+        if (_IsHardwareMatch(Hardware, gcv600, 0x4653))
+        {
+            available = gcvTRUE;
+        }
+
         break;
 
     case gcvFEATURE_DEC300_COMPRESSION:
@@ -1582,6 +1593,22 @@ _QueryFeatureDatabase(
         available = database->USC_FULL_CACHE_FIX;
         break;
 
+    case gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX:
+        available = database->PE_TILE_CACHE_FLUSH_FIX;
+        break;
+
+    case gcvFEATURE_TILE_STATUS_2BITS:
+        available = database->REG_TileStatus2Bits;
+        break;
+
+    case gcvFEATURE_128BTILE:
+        available = database->CACHE128B256BPERLINE;
+        break;
+
+    case gcvFEATURE_COMPRESSION_DEC400:
+        available = database->DEC400;
+        break;
+
     case gcvFEATURE_SUPPORT_GCREGTX:
         available = database->REG_Halti1;
 
@@ -1592,6 +1619,10 @@ _QueryFeatureDatabase(
         }
         break;
 
+    case gcvFEATURE_MSAA_FRAGMENT_OPERATION:
+        available = database->MSAA_FRAGMENT_OPERATION;
+        break;
+
     case gcvFEATURE_OCB_COUNTER:
         available = database->OCB_COUNTER;
         break;
@@ -1725,7 +1756,6 @@ _SetHardwareOptions(
     )
 {
     gceSTATUS status;
-    gctUINT i;
     gctUINT64 data = 0;
     gcsHAL_QUERY_CHIP_OPTIONS *options = &Hardware->options;
     gcsFEATURE_DATABASE *database = Hardware->featureDatabase;
@@ -1735,8 +1765,6 @@ _SetHardwareOptions(
     gctBOOL featureTS = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TESSELLATION) ? gcvTRUE : gcvFALSE;
     gctUINT32 featureL1CacheSize = database->L1CacheSize;
     gctUINT32 featureUSCMaxPages = database->USC_MAX_PAGES;
-    gctBOOL featureGS = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GEOMETRY_SHADER) ? gcvTRUE : gcvFALSE;
-    gctBOOL featureUSCFullCacheFix = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC_FULLCACHE_FIX) ? gcvTRUE : gcvFALSE;
 
 
     status = gckOS_QueryOption(Hardware->os, "powerManagement", &data);
@@ -1767,35 +1795,9 @@ _SetHardwareOptions(
         options->enableMMU = gcvFALSE;
     }
 
-    {    Hardware->options.uscAttribCacheRatio = 0x2;
-       if (featureUSC)    {        if (featureSeparateLS)        {            Hardware->options.uscL1CacheRatio = 0x0;
-        }        else        {            gctUINT L1cacheSize;
-                       if (featureComputeOnly)            {                L1cacheSize = featureL1CacheSize;
-            }            else            {                gctUINT attribBufSizeInKB;
-                if (featureTS)                {                    gcmkASSERT(featureGS);
-                    featureGS = featureGS;
-                    attribBufSizeInKB = 42;
-                }                else                {                    gcmkASSERT(!featureGS);
-                    attribBufSizeInKB = 8;
-                }                L1cacheSize = featureUSCMaxPages - attribBufSizeInKB;
-            }            gcmkASSERT(L1cacheSize);
-            if (L1cacheSize >= featureL1CacheSize)            {                Hardware->options.uscL1CacheRatio = 0x0;
-                gcmkASSERT(featureUSCFullCacheFix);
-                featureUSCFullCacheFix = featureUSCFullCacheFix;
-            }            else            {                static const gctINT s_uscCacheRatio[] =                {                    100000,                    50000,                    25000,                    12500,                    62500,                    3125,                    75000,                    0,                };
-                gctINT maxL1cacheSize = L1cacheSize * 100000;
-                gctINT delta = 2147483647;
-                gctINT i = 0;
-                gctINT curIndex = -1;
-                for (;
- i < gcmCOUNTOF(s_uscCacheRatio);
- ++i)                {                    gctINT curL1cacheSize = featureL1CacheSize * s_uscCacheRatio[i];
-                                     if ((maxL1cacheSize >= curL1cacheSize) &&                        ((maxL1cacheSize - curL1cacheSize) < delta))                    {                        curIndex = i;
-                        delta = maxL1cacheSize - curL1cacheSize;
-                    }                }                gcmkASSERT(-1 != curIndex);
-                Hardware->options.uscL1CacheRatio = curIndex;
-            }        }    }};
-
+    gcmCONFIGUSC2(gcmk, featureUSC, featureSeparateLS, featureComputeOnly, featureTS,
+                 featureL1CacheSize, featureUSCMaxPages,
+                 Hardware->options.uscAttribCacheRatio, Hardware->options.uscL1CacheRatio);
 
     status = gckOS_QueryOption(Hardware->os, "smallBatch", &data);
     options->smallBatch = (data != 0);
@@ -1820,12 +1822,6 @@ _SetHardwareOptions(
         options->userClusterMask= Hardware->identity.clusterAvailMask;
     }
 
-    for (i = 0; i < gcvSRAM_COUNT; i++)
-    {
-        options->sRAMBaseAddresses[i] = gcvINVALID_ADDRESS;
-        options->sRAMPhysicalBases[i] = gcvINVALID_PHYSICAL_ADDRESS;
-    }
-
     options->secureMode = gcvSECURE_NONE;
 
     if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY))
@@ -2001,42 +1997,46 @@ _SetupSRAMVidMem(
     gceSTATUS status = gcvSTATUS_OK;
     gctUINT i;
 
-    for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_COUNT; i++)
+    for (i = gcvSRAM_INTERNAL0; i < gcvSRAM_INTER_COUNT; i++)
     {
         if (Hardware->identity.sRAMSizes[i] &&
            (Hardware->identity.sRAMBases[i] != gcvINVALID_PHYSICAL_ADDRESS))
         {
-            char sRAMName[20];
-            gcmkSPRINTF(sRAMName, gcmSIZEOF(sRAMName) - 1, "GPU core%d axi sram%d", Hardware->core, i);
-
-            gcmkPRINT("%s\n", sRAMName);
-
+            /* If the internal SRAM usage is memory block. */
             status = gckVIDMEM_Construct(
                 Hardware->os,
                 Hardware->identity.sRAMBases[i],
                 Hardware->identity.sRAMSizes[i],
                 64,
                 0,
-                &Hardware->sRAMVideoMem[i]
+                &Hardware->sRAMVidMem[i]
                 );
 
             if (gcmIS_ERROR(status))
             {
                 Hardware->identity.sRAMSizes[i] = 0;
-                Hardware->sRAMVideoMem[i] = gcvNULL;
+                Hardware->sRAMVidMem[i] = gcvNULL;
             }
             else
             {
+                char sRAMName[20];
+                gctUINT64 data = 0;
+                gctBOOL sRAMRequested;
+
+                gcmkSPRINTF(sRAMName, gcmSIZEOF(sRAMName) - 1, "Galcore core%d sram%d", Hardware->core, i);
+                status = gckOS_QueryOption(Hardware->os, "sRAMRequested", (gctUINT64 *)&data);
+                sRAMRequested = (status == gcvSTATUS_OK) ? (data != 0) : gcvFALSE;
+
                 gcmkONERROR(gckOS_RequestReservedMemory(
                     Hardware->os,
                     Hardware->identity.sRAMBases[i],
                     Hardware->identity.sRAMSizes[i],
                     sRAMName,
-                    0,
+                    sRAMRequested,
                     &Hardware->sRAMPhysical[i]
                     ));
 
-                Hardware->sRAMVideoMem[i]->physical = Hardware->sRAMPhysical[i];
+                Hardware->sRAMVidMem[i]->physical = Hardware->sRAMPhysical[i];
             }
         }
     }
@@ -2116,10 +2116,7 @@ gckHARDWARE_Construct(
     gcmkONERROR(_IdentifyHardwareByDatabase(hardware, Os, Device, Core, &hardware->identity));
 
     /* Setup SRAM memory heap. */
-    if (hardware->sRAMNonExclusive)
-    {
-        gcmkONERROR(_SetupSRAMVidMem(hardware));
-    }
+    gcmkONERROR(_SetupSRAMVidMem(hardware));
 
     _SetHardwareOptions(hardware);
 
@@ -2246,23 +2243,11 @@ gckHARDWARE_Construct(
     gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
     gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
 
-#if gcdPOWER_MANAGEMENT_REFINEMENT
     gcmkVERIFY_OK(gckOS_CreateTimer(Os,
                                     _PowerStateTimerFunc,
                                     (gctPOINTER)hardware,
                                     &hardware->powerStateTimer));
 
-#else
-#if gcdPOWEROFF_TIMEOUT
-    hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
-
-    gcmkVERIFY_OK(gckOS_CreateTimer(Os,
-                                    _PowerTimerFunction,
-                                    (gctPOINTER)hardware,
-                                    &hardware->powerOffTimer));
-#endif
-#endif
-
     for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
     {
         gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty[i]));
@@ -2342,21 +2327,11 @@ OnError:
             gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
         }
 
-#if gcdPOWER_MANAGEMENT_REFINEMENT
         if (hardware->powerStateTimer != gcvNULL)
         {
             gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerStateTimer));
             gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerStateTimer));
         }
-#else
-#if gcdPOWEROFF_TIMEOUT
-        if (hardware->powerOffTimer != gcvNULL)
-        {
-            gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
-            gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
-        }
-#endif
-#endif
 
         for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
         {
@@ -2540,15 +2515,8 @@ gckHARDWARE_Destroy(
     /* Destroy the power mutex. */
     gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex));
 
-#if gcdPOWER_MANAGEMENT_REFINEMENT
     gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerStateTimer));
     gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerStateTimer));
-#else
-#if gcdPOWEROFF_TIMEOUT
-    gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
-    gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
-#endif
-#endif
 
     for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
     {
@@ -3032,6 +3000,8 @@ gckHARDWARE_InitializeHardware(
 
     if (_IsHardwareMatch(Hardware, gcv4000, 0x5222)
      || _IsHardwareMatch(Hardware, gcv2000, 0x5108)
+     || _IsHardwareMatch(Hardware, gcv7000, 0x6202)
+     || _IsHardwareMatch(Hardware, gcv7000, 0x6203)
      || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TX_DESCRIPTOR)
        && !gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TX_DESC_CACHE_CLOCKGATE_FIX)
         )
@@ -4370,6 +4340,7 @@ _ResumeWaitLinkFE(
     gckHARDWARE Hardware
     )
 {
+    gceSTATUS status;
     gctUINT32 resume;
     gctUINT32 bytes;
     gctUINT32 idle;
@@ -4377,10 +4348,10 @@ _ResumeWaitLinkFE(
     /* Make sure FE is idle. */
     do
     {
-        gckOS_ReadRegisterEx(Hardware->os,
+        gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
                              Hardware->core,
                              0x00004,
-                             &idle);
+                             &idle));
     }
     while (idle != 0x7FFFFFFF);
 
@@ -4398,20 +4369,23 @@ _ResumeWaitLinkFE(
  ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))),
              idle);
 
-    gckOS_ReadRegisterEx(Hardware->os,
+    gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
                          Hardware->core,
                          0x00664,
-                         &resume);
+                         &resume));
 
-    gckOS_ReadRegisterEx(Hardware->os,
+    gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
                          Hardware->core,
                          0x00664,
-                         &resume);
+                         &resume));
 
     bytes = Hardware->hasL2Cache ? 24 : 16;
 
     /* Start Command Parser. */
     gckWLFE_AtomicExecute(Hardware, resume, bytes);
+
+OnError:
+    return;
 }
 
 /*******************************************************************************
@@ -4736,7 +4710,7 @@ gckHARDWARE_SetMMU(
     if (Hardware->mmuVersion == 0)
     {
         /* mmu v0 only support 1 level translation, only uses stlb level mapping. */
-        gcmkSAFECASTPHYSADDRT(address, Mmu->dynamicArea.stlbPhysical);
+        gcmkSAFECASTPHYSADDRT(address, Mmu->dynamicArea4K.stlbPhysical);
 
         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
                        "Setting page table to 0x%08X",
@@ -5987,7 +5961,6 @@ gckHARDWARE_FlushMcfeMMU(
     IN OUT gctUINT32 * Bytes
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gceSTATUS status;
     gctUINT32_PTR buffer;
     gctUINT32 flushSize;
@@ -6104,42 +6077,36 @@ gckHARDWARE_FlushMcfeMMU(
 
         /* SubmitJob. */
         *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x16 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_SUBMIT_JOB & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)));
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) (0x001 & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
         *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
     }
 
     if (Bytes)
@@ -6156,9 +6123,6 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 static gceSTATUS
@@ -6344,6 +6308,14 @@ _ProgramMMUStates(
                 entry->high = extMtlb;
             }
 
+            gcmkDUMP(Mmu->os, "#[mmu: page table array]");
+
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address, entry->low, 4);
+
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address + 4, entry->high, 4);
+
             gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
                 Hardware->kernel,
                 Hardware->pagetableArray.videoMem,
@@ -7033,7 +7005,6 @@ _ProgramMMUStatesMCFE(
     IN OUT gctUINT32 * Bytes
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gceSTATUS status = gcvSTATUS_OK;
     gctUINT32 config, address;
     gctUINT32 extMtlb, extSafeAddress, configEx = 0;
@@ -7187,6 +7158,14 @@ _ProgramMMUStatesMCFE(
                 entry->high = extMtlb;
             }
 
+            gcmkDUMP(Mmu->os, "#[mmu: page table array]");
+
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address, entry->low, 4);
+
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address + 4, entry->high, 4);
+
             gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
                 Hardware->kernel,
                 Hardware->pagetableArray.videoMem,
@@ -7253,29 +7232,25 @@ _ProgramMMUStatesMCFE(
  ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))));
 
             *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
             *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
         }
         else
         {
@@ -7386,29 +7361,25 @@ _ProgramMMUStatesMCFE(
                 *buffer++ = configEx;
 
                 *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
                 *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
             }
         }
     }
@@ -7426,9 +7397,6 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 /*******************************************************************************
@@ -7603,6 +7571,8 @@ gckHARDWARE_Flush(
     gctBOOL flushTXDescCache;
     gctBOOL flushTFB;
     gctBOOL hwTFB;
+    gctBOOL blt;
+    gctBOOL peTSFlush;
     gctBOOL multiCluster;
 
     gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
@@ -7618,8 +7588,11 @@ gckHARDWARE_Flush(
 
     hwTFB = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HW_TFB);
 
+    blt = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE);
     multiCluster = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MULTI_CLUSTER);
 
+    peTSFlush = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX);
+
     /* Flush tile status cache. */
     flushTileStatus = Flush & gcvFLUSH_TILE_STATUS;
 
@@ -7744,7 +7717,9 @@ gckHARDWARE_Flush(
     /* Vertex buffer and texture could be touched by SHL1 for SSBO and image load/store */
     if ((Flush & (gcvFLUSH_VERTEX | gcvFLUSH_TEXTURE)) && (pipe == 0x0))
     {
-        flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        if (Hardware->identity.chipModel != 0x8000 || Hardware->identity.chipRevision != 0x7120 || !Hardware->options.enableNNTPParallel)
+        {
+            flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  5:5) - (0 ?
  5:5) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7754,7 +7729,7 @@ gckHARDWARE_Flush(
  5:5) - (0 ?
  5:5) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
-               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  10:10) - (0 ?
  10:10) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7764,7 +7739,7 @@ gckHARDWARE_Flush(
  10:10) - (0 ?
  10:10) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 10:10) - (0 ? 10:10) + 1))))))) << (0 ? 10:10)))
-               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  11:11) - (0 ?
  11:11) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7774,6 +7749,40 @@ gckHARDWARE_Flush(
  11:11) - (0 ?
  11:11) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)));
+        }
+        else
+        {
+            flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1))))))) << (0 ?
+ 10:10))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 10:10) - (0 ?
+ 10:10) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 10:10) - (0 ? 10:10) + 1))))))) << (0 ? 10:10)))
+                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1))))))) << (0 ?
+ 11:11))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 11:11) - (0 ?
+ 11:11) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)));
+        }
     }
 
     /* See if there is a valid flush. */
@@ -7800,7 +7809,7 @@ gckHARDWARE_Flush(
         if (!txCacheFix || flushICache || flushTXDescCache)
         {
             /* Semaphore/Stall */
-            reserveBytes += 4 * gcmSIZEOF(gctUINT32);
+            reserveBytes += blt ? (8 * gcmSIZEOF(gctUINT32)) : (4 * gcmSIZEOF(gctUINT32));
         }
 
         if (flush)
@@ -7815,7 +7824,7 @@ gckHARDWARE_Flush(
 
         if (flushTileStatus)
         {
-            reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+            reserveBytes += (!peTSFlush && blt) ? 6 * gcmSIZEOF(gctUINT32) : 2 * gcmSIZEOF(gctUINT32);
         }
 
         if (flushICache)
@@ -7834,15 +7843,13 @@ gckHARDWARE_Flush(
         }
 
         /* Semaphore/Stall */
-        reserveBytes += 4 * gcmSIZEOF(gctUINT32);
+        reserveBytes += blt ? (8 * gcmSIZEOF(gctUINT32)) : (4 * gcmSIZEOF(gctUINT32));
 
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
         if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MCFE) && (reserveBytes & 8))
         {
             appendNop = gcvTRUE;
             reserveBytes += 8;
         }
-#endif
 
         /* Copy to command queue. */
         if (Logical != gcvNULL)
@@ -7855,9 +7862,11 @@ gckHARDWARE_Flush(
 
             if (!txCacheFix || flushICache || flushTXDescCache)
             {
-                /* Semaphore. */
-                *logical++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                if (blt)
+                {
+                    /* Semaphore from FE to BLT. */
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7867,7 +7876,7 @@ gckHARDWARE_Flush(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7877,7 +7886,51 @@ gckHARDWARE_Flush(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7888,8 +7941,8 @@ gckHARDWARE_Flush(
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-                *logical++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7899,20 +7952,20 @@ gckHARDWARE_Flush(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  12:8) - (0 ?
  12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
-                /* Stall. */
-                *logical++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    /* Stall from FE to BLT. */
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7923,8 +7976,8 @@ gckHARDWARE_Flush(
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
-                *logical++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7934,23 +7987,19 @@ gckHARDWARE_Flush(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  12:8) - (0 ?
  12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-            }
 
-            if (flush)
-            {
-                /* Append LOAD_STATE to AQFlush. */
-                *logical++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7960,17 +8009,7 @@ gckHARDWARE_Flush(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7979,7 +8018,158 @@ gckHARDWARE_Flush(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+                }
+                else
+                {
+                    /* Semaphore. */
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                    /* Stall. */
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+                }
+            }
+
+            if (flush)
+            {
+                /* Append LOAD_STATE to AQFlush. */
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
                 *logical++ = flush;
 
@@ -8028,8 +8218,10 @@ gckHARDWARE_Flush(
 
             if (flushTileStatus)
             {
-                *logical++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                if (!peTSFlush && blt)
+                {
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8039,7 +8231,141 @@ gckHARDWARE_Flush(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+                }
+                else
+                {
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8049,7 +8375,7 @@ gckHARDWARE_Flush(
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8060,8 +8386,8 @@ gckHARDWARE_Flush(
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-                *logical++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    *logical++
+                        = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8071,6 +8397,7 @@ gckHARDWARE_Flush(
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+                }
 
                 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
                                "0x%x: FLUSH TILE STATUS 0x%x", logical - 1, logical[-1]);
@@ -8253,16 +8580,18 @@ gckHARDWARE_Flush(
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
                 *logical++
-                    = 0x12345678;
+                    = 0x1;
 
                 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
                                "0x%x: FLUSH TFB cache 0x%x", logical - 1, logical[-1]);
 
             }
 
-            /* Semaphore. */
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (blt)
+            {
+                /* Semaphore from FE to BLT. */
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8272,7 +8601,7 @@ gckHARDWARE_Flush(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8282,7 +8611,51 @@ gckHARDWARE_Flush(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8293,8 +8666,8 @@ gckHARDWARE_Flush(
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8304,20 +8677,20 @@ gckHARDWARE_Flush(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  12:8) - (0 ?
  12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
-            /* Stall. */
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                /* Stall from FE to BLT. */
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8328,8 +8701,8 @@ gckHARDWARE_Flush(
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8339,48 +8712,178 @@ gckHARDWARE_Flush(
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  12:8) - (0 ?
  12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
-            if (appendNop)
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+            }
+            else
             {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+                /* Semaphore. */
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
                 *logical++
                     = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+                /* Stall. */
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
                 *logical++
                     = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
MCFE_COMMAND_OPCODE) - (0 ?
MCFE_COMMAND_OPCODE) + 1) == 32) ?
4:0) - (0 ?
4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
-#endif
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
+            if (appendNop)
+            {
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
             }
         }
 
@@ -8555,7 +9058,6 @@ _PowerEnum(gceCHIPPOWERSTATE State)
 }
 #endif
 
-#if gcdPOWER_MANAGEMENT_REFINEMENT
 static gceSTATUS
 _PmClockOn(
     IN gckHARDWARE Hardware,
@@ -9121,6 +9623,7 @@ _PmSetPowerOffDirection(
 
         /* Power off, clock off. */
         gcmkONERROR(_PmClockOff(Hardware, gcvFALSE));
+
         break;
 
     default:
@@ -9135,7 +9638,7 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckHARDWARE_SetPowerManagementState
+**  gckHARDWARE_SetPowerState
 **
 **  Set GPU to a specified power state.
 **
@@ -9149,7 +9652,7 @@ OnError:
 **
 */
 gceSTATUS
-gckHARDWARE_SetPowerManagementState(
+gckHARDWARE_SetPowerState(
     IN gckHARDWARE Hardware,
     IN gceCHIPPOWERSTATE State
     )
@@ -9343,1176 +9846,142 @@ gckHARDWARE_SetPowerManagementState(
             {
                 /* Done. */
                 status = gcvSTATUS_OK;
-                goto OnError;
-            }
-        }
-        else
-        {
-            /* Check error. */
-            gcmkONERROR(status);
-        }
-
-        /* We just check if in non-global state, but need not to acquire it. */
-        gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
-        globalAcquired = gcvFALSE;
-    }
-
-    if (Hardware->chipPowerState == gcvPOWER_ON)
-    {
-        /* Switch from power ON to other non-runnable states. */
-        if (broadcast)
-        {
-            gctINT32 atomValue;
-
-            /* Try to acquire the semaphore to block/sync with commit. */
-            status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore);
-
-            if (gcmIS_ERROR(status))
-            {
-                status = gcvSTATUS_CHIP_NOT_READY;
-                goto OnError;
-            }
-
-            acquired = gcvTRUE;
-
-            /* Check commit atom, abort when commit is in progress. */
-            gcmkONERROR(gckOS_AtomGet(Hardware->os,
-                                      command->atomCommit,
-                                      &atomValue));
-
-            if (atomValue > 0)
-            {
-                status = gcvSTATUS_CHIP_NOT_READY;
-                goto OnError;
-            }
-        }
-        else
-        {
-            /* Acquire/wait the semaphore to block/sync with command commit. */
-            gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
-            acquired = gcvTRUE;
-        }
-    }
-
-    /* Do hardware power state change. */
-    if (Hardware->chipPowerState < state)
-    {
-        /* On to off direction. */
-        gcmkONERROR(_PmSetPowerOffDirection(Hardware, state, broadcast));
-    }
-    else
-    {
-        /* Off to on direction. */
-        gcmkONERROR(_PmSetPowerOnDirection(Hardware, state));
-    }
-
-    if (status == gcvSTATUS_CHIP_NOT_READY)
-    {
-        /* CHIP_NOT_READY is not an error, either not success. */
-        goto OnError;
-    }
-
-    if (state == gcvPOWER_ON)
-    {
-        /* Switched to power ON from other non-runnable states. */
-        gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
-        acquired = gcvFALSE;
-
-        if (global)
-        {
-            /*
-             * Global semaphore should be acquired already before, when
-             * global OFF, IDLE or SUSPEND.
-             */
-            status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
-
-            if (status != gcvSTATUS_TIMEOUT)
-            {
-                gcmkPRINT("%s: global state error", __FUNCTION__);
-            }
-
-            /* Switched to global ON, now release the global semaphore. */
-            gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
-            globalAcquired = gcvFALSE;
-        }
-    }
-
-    gckSTATETIMER_Accumulate(&Hardware->powerStateCounter,
-                             Hardware->chipPowerState);
-
-    /* Save the new power state. */
-    Hardware->chipPowerState = state;
-
-#if gcdDVFS
-    if (state == gcvPOWER_ON && Hardware->kernel->dvfs)
-    {
-        gckDVFS_Start(Hardware->kernel->dvfs);
-    }
-#endif
-
-    if (!broadcast)
-    {
-        /*
-         * Cancel delayed power state change.
-         * Stop timer is not as good as set as no state change. Timer may run
-         * into this function already when try to to stop the timer.
-         */
-        Hardware->nextPowerState = gcvPOWER_INVALID;
-    }
-
-    if (state == gcvPOWER_IDLE || state == gcvPOWER_SUSPEND)
-    {
-        /* Delayed power off. */
-        Hardware->nextPowerState = gcvPOWER_OFF_TIMEOUT;
-
-        /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
-        gcmkVERIFY_OK(gckOS_StartTimer(os, Hardware->powerStateTimer, 100));
-    }
-
-    /* Release the power mutex. */
-    gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    if (acquired)
-    {
-        /* Release semaphore. */
-        gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
-                                             command->powerSemaphore));
-    }
-
-    if (globalAcquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
-                                             Hardware->globalSemaphore));
-    }
-
-    if (mutexAcquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
-    }
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-#else
-
-typedef enum
-{
-    gcvPOWER_FLAG_INITIALIZE    = 1 << 0,
-    gcvPOWER_FLAG_STALL         = 1 << 1,
-    gcvPOWER_FLAG_STOP          = 1 << 2,
-    gcvPOWER_FLAG_START         = 1 << 3,
-    gcvPOWER_FLAG_RELEASE       = 1 << 4,
-    gcvPOWER_FLAG_DELAY         = 1 << 5,
-    gcvPOWER_FLAG_SAVE          = 1 << 6,
-    gcvPOWER_FLAG_ACQUIRE       = 1 << 7,
-    gcvPOWER_FLAG_POWER_OFF     = 1 << 8,
-    gcvPOWER_FLAG_CLOCK_OFF     = 1 << 9,
-    gcvPOWER_FLAG_CLOCK_ON      = 1 << 10,
-}
-gcePOWER_FLAGS;
-
-/*******************************************************************************
-**
-**  gckHARDWARE_SetPowerManagementState
-**
-**  Set GPU to a specified power state.
-**
-**  INPUT:
-**
-**      gckHARDWARE Harwdare
-**          Pointer to an gckHARDWARE object.
-**
-**      gceCHIPPOWERSTATE State
-**          Power State.
-**
-*/
-gceSTATUS
-gckHARDWARE_SetPowerManagementState(
-    IN gckHARDWARE Hardware,
-    IN gceCHIPPOWERSTATE State
-    )
-{
-    gceSTATUS status;
-    gckCOMMAND command = gcvNULL;
-    gckOS os;
-    gctUINT flag, clock;
-    gctBOOL acquired = gcvFALSE;
-    gctBOOL mutexAcquired = gcvFALSE;
-    gctBOOL broadcast = gcvFALSE;
-#if gcdPOWEROFF_TIMEOUT
-    gctBOOL timeout = gcvFALSE;
-    gctBOOL isAfter = gcvFALSE;
-    gctUINT32 currentTime;
-#endif
-    gctUINT32 process, thread;
-    gctBOOL commandStarted = gcvFALSE;
-
-#if gcdENABLE_PROFILING
-    gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
-              initTime, offTime, startTime, totalTime;
-#endif
-    gctBOOL global = gcvFALSE;
-    gctBOOL globalAcquired = gcvFALSE;
-
-    /* State transition flags. */
-    static const gctUINT flags[4][4] =
-    {
-        /* gcvPOWER_ON           */
-        {   /* ON                */ 0,
-            /* IDLE              */ gcvPOWER_FLAG_ACQUIRE   |
-                                    gcvPOWER_FLAG_STALL,
-            /* SUSPEND           */ gcvPOWER_FLAG_ACQUIRE   |
-                                    gcvPOWER_FLAG_STALL     |
-                                    gcvPOWER_FLAG_STOP      |
-                                    gcvPOWER_FLAG_CLOCK_OFF,
-            /* OFF               */ gcvPOWER_FLAG_ACQUIRE   |
-                                    gcvPOWER_FLAG_STALL     |
-                                    gcvPOWER_FLAG_STOP      |
-                                    gcvPOWER_FLAG_POWER_OFF |
-                                    gcvPOWER_FLAG_CLOCK_OFF,
-        },
-
-        /* gcvPOWER_IDLE         */
-        {   /* ON                */ gcvPOWER_FLAG_RELEASE,
-            /* IDLE              */ 0,
-            /* SUSPEND           */ gcvPOWER_FLAG_STOP      |
-                                    gcvPOWER_FLAG_CLOCK_OFF,
-            /* OFF               */ gcvPOWER_FLAG_STOP      |
-                                    gcvPOWER_FLAG_POWER_OFF |
-                                    gcvPOWER_FLAG_CLOCK_OFF,
-        },
-
-        /* gcvPOWER_SUSPEND      */
-        {   /* ON                */ gcvPOWER_FLAG_START     |
-                                    gcvPOWER_FLAG_RELEASE   |
-                                    gcvPOWER_FLAG_DELAY     |
-                                    gcvPOWER_FLAG_CLOCK_ON,
-            /* IDLE              */ gcvPOWER_FLAG_START     |
-                                    gcvPOWER_FLAG_DELAY     |
-                                    gcvPOWER_FLAG_CLOCK_ON,
-            /* SUSPEND           */ 0,
-            /* OFF               */ gcvPOWER_FLAG_SAVE      |
-                                    gcvPOWER_FLAG_POWER_OFF |
-                                    gcvPOWER_FLAG_CLOCK_OFF,
-        },
-
-        /* gcvPOWER_OFF          */
-        {   /* ON                */ gcvPOWER_FLAG_INITIALIZE |
-                                    gcvPOWER_FLAG_START      |
-                                    gcvPOWER_FLAG_RELEASE    |
-                                    gcvPOWER_FLAG_DELAY,
-            /* IDLE              */ gcvPOWER_FLAG_INITIALIZE |
-                                    gcvPOWER_FLAG_START      |
-                                    gcvPOWER_FLAG_DELAY,
-            /* SUSPEND           */ gcvPOWER_FLAG_INITIALIZE |
-                                    gcvPOWER_FLAG_CLOCK_OFF,
-            /* OFF               */ 0,
-        },
-    };
-
-    /* Clocks. */
-    static const gctUINT clocks[4] =
-    {
-        /* gcvPOWER_ON */
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
-
-        /* gcvPOWER_IDLE */
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
-
-        /* gcvPOWER_SUSPEND */
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
-
-        /* gcvPOWER_OFF */
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
-        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
-    };
-
-    gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
-#if gcmIS_DEBUG(gcdDEBUG_TRACE)
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                   "Switching to power state %d(%s)",
-                   State, _PowerEnum(State));
-#endif
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-
-    /* Get the gckOS object pointer. */
-    os = Hardware->os;
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-
-    /* Get the gckCOMMAND object pointer. */
-    gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
-    command = Hardware->kernel->command;
-    gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
-
-    /* Start profiler. */
-    gcmkPROFILE_INIT(freq, time);
-
-    /* Convert the broadcast power state. */
-    switch (State)
-    {
-    case gcvPOWER_IDLE_BROADCAST:
-        /* Convert to IDLE and note we are inside broadcast. */
-        State     = gcvPOWER_IDLE;
-        broadcast = gcvTRUE;
-        break;
-
-    case gcvPOWER_SUSPEND_BROADCAST:
-        /* Convert to SUSPEND and note we are inside broadcast. */
-        State     = gcvPOWER_SUSPEND;
-        broadcast = gcvTRUE;
-        break;
-
-    case gcvPOWER_OFF_BROADCAST:
-        /* Convert to OFF and note we are inside broadcast. */
-        State     = gcvPOWER_OFF;
-        broadcast = gcvTRUE;
-        break;
-
-    case gcvPOWER_ON_AUTO:
-        /* Convert to ON and note we are inside recovery. */
-        State = gcvPOWER_ON;
-        break;
-
-    case gcvPOWER_ON:
-    case gcvPOWER_IDLE:
-    case gcvPOWER_SUSPEND:
-    case gcvPOWER_OFF:
-        /* Mark as global power management. */
-        global = gcvTRUE;
-        break;
-
-#if gcdPOWEROFF_TIMEOUT
-    case gcvPOWER_OFF_TIMEOUT:
-        /* Convert to OFF and note we are inside broadcast. */
-        State     = gcvPOWER_OFF;
-        broadcast = gcvTRUE;
-        /* Check time out */
-        timeout = gcvTRUE;
-        break;
-#endif
-
-    default:
-        break;
-    }
-
-    if ((Hardware->options.powerManagement == gcvFALSE) &&
-        (Hardware->chipPowerState == gcvPOWER_ON || State != gcvPOWER_ON))
-    {
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-
-    /* Get current process and thread IDs. */
-    gcmkONERROR(gckOS_GetProcessID(&process));
-    gcmkONERROR(gckOS_GetThreadID(&thread));
-
-    if (broadcast)
-    {
-        /* Try to acquire the power mutex. */
-        status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
-
-        if (gcmIS_SUCCESS(status))
-        {
-            mutexAcquired = gcvTRUE;
-        }
-        else if (status == gcvSTATUS_TIMEOUT)
-        {
-            /* Check if we already own this mutex. */
-            if ((Hardware->powerProcess == process)
-            &&  (Hardware->powerThread  == thread)
-            )
-            {
-                /* Bail out on recursive power management. */
-                gcmkFOOTER_NO();
-                return gcvSTATUS_OK;
-            }
-            else if (State != gcvPOWER_ON)
-            {
-                /* Called from IST,
-                ** so waiting here will cause deadlock,
-                ** if lock holder call gckCOMMAND_Stall() */
-                status = gcvSTATUS_OK;
-                goto OnError;
-            }
-        }
-    }
-
-    if (!mutexAcquired)
-    {
-        /* Acquire the power mutex. */
-        gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
-        mutexAcquired = gcvTRUE;
-    }
-
-    /* Get time until mtuex acquired. */
-    gcmkPROFILE_QUERY(time, mutexTime);
-
-    Hardware->powerProcess = process;
-    Hardware->powerThread  = thread;
-
-    /* Grab control flags and clock. */
-    flag  = flags[Hardware->chipPowerState][State];
-    clock = clocks[State];
-
-#if gcdENABLE_FSCALE_VAL_ADJUST
-    if (State == gcvPOWER_ON)
-    {
-        clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
-    }
-#endif
-
-    if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
-    {
-#if gcdPOWER_SUSPEND_WHEN_IDLE
-    /* Do nothing */
-
-        /* Release the power mutex. */
-        gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-
-           gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
-#else
-    /* Clock should be on when switch power from off to suspend */
-        clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
-                ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
-                ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
-                ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) ;
-#endif
-    }
-
-#if gcdPOWEROFF_TIMEOUT
-    if (timeout)
-    {
-        gcmkONERROR(gckOS_GetTicks(&currentTime));
-
-        gcmkONERROR(
-            gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
-
-        /* powerOffTime is pushed forward, give up.*/
-        if (isAfter
-        /* Expect a transition start from IDLE or SUSPEND. */
-        ||  (Hardware->chipPowerState == gcvPOWER_ON)
-        ||  (Hardware->chipPowerState == gcvPOWER_OFF)
-        )
-        {
-            /* Release the power mutex. */
-            gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-
-            /* No need to do anything. */
-            gcmkFOOTER_NO();
-            return gcvSTATUS_OK;
-        }
-
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                       "Power Off GPU[%d] at %u [supposed to be at %u]",
-                       Hardware->core, currentTime, Hardware->powerOffTime);
-    }
-#endif
-
-    if (flag == 0)
-    {
-        /* Release the power mutex. */
-        gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-
-        /* No need to do anything. */
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-
-    /* If this is an internal power management, we have to check if we can grab
-    ** the global power semaphore. If we cannot, we have to wait until the
-    ** external world changes power management. */
-    if (!global)
-    {
-        /* Try to acquire the global semaphore. */
-        status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
-        if (status == gcvSTATUS_TIMEOUT)
-        {
-            if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
-            {
-                /* Called from thread routine which should NEVER sleep.*/
-                status = gcvSTATUS_OK;
-                goto OnError;
-            }
-
-            /* Release the power mutex. */
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                           "Releasing the power mutex.");
-            gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-            mutexAcquired = gcvFALSE;
-
-            /* Wait for the semaphore. */
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                           "Waiting for global semaphore.");
-            gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
-            globalAcquired = gcvTRUE;
-
-            /* Acquire the power mutex. */
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                           "Reacquiring the power mutex.");
-            gcmkONERROR(gckOS_AcquireMutex(os,
-                                           Hardware->powerMutex,
-                                           gcvINFINITE));
-            mutexAcquired = gcvTRUE;
-
-            /* chipPowerState may be changed by external world during the time
-            ** we give up powerMutex, so updating flag now is necessary. */
-            flag = flags[Hardware->chipPowerState][State];
-
-            if (flag == 0)
-            {
-                gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
-                globalAcquired = gcvFALSE;
-
-                gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-                mutexAcquired = gcvFALSE;
-
-                gcmkFOOTER_NO();
-                return gcvSTATUS_OK;
-            }
-        }
-        else
-        {
-            /* Error. */
-            gcmkONERROR(status);
-        }
-
-        /* Release the global semaphore again. */
-        gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
-        globalAcquired = gcvFALSE;
-
-        /* Try to acquire the semaphore to make sure commit is not in progress
-        ** Otherwise, we just abort. */
-        if (flag & gcvPOWER_FLAG_ACQUIRE)
-        {
-            /* ON -> Other, boardcast. */
-            /* Try to acquire the power management semaphore. */
-            status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore);
-
-            if (status == gcvSTATUS_OK)
-            {
-                acquired = gcvTRUE;
-
-                /* avoid acquiring again. */
-                flag &= ~gcvPOWER_FLAG_ACQUIRE;
-            }
-            else
-            {
-                /* Not ready to swith. */
-                status = gcvSTATUS_CHIP_NOT_READY;
-                goto OnError;
-            }
-        }
-    }
-    else
-    {
-        if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
-        {
-            /* Acquire the global semaphore if it has not been acquired. */
-            status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
-            if (status == gcvSTATUS_OK)
-            {
-                globalAcquired = gcvTRUE;
-            }
-            else if (status != gcvSTATUS_TIMEOUT)
-            {
-                /* Other errors. */
-                gcmkONERROR(status);
-            }
-            /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
-            ** gcvSTATUS_TIMEOUT means global semaphore has already
-            ** been acquired before this operation, so even if we fail,
-            ** we should not release it in our error handling. It should be
-            ** released by the next successful global gcvPOWER_ON. */
-        }
-
-        /* Global power management can't be aborted, so sync with
-        ** proceeding last commit. */
-        if (flag & gcvPOWER_FLAG_ACQUIRE)
-        {
-            /* Acquire the power management semaphore. */
-            gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
-            acquired = gcvTRUE;
-
-            /* avoid acquiring again. */
-            flag &= ~gcvPOWER_FLAG_ACQUIRE;
-        }
-    }
-
-    if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
-    {
-        /* Turn on the power. */
-        gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
-
-        /* Mark clock and power as enabled. */
-        Hardware->clockState = gcvTRUE;
-        Hardware->powerState = gcvTRUE;
-
-        for (;;)
-        {
-            /* Check if GPU is present and awake. */
-            status = _IsGPUPresent(Hardware);
-
-            /* Check if the GPU is not responding. */
-            if (status == gcvSTATUS_GPU_NOT_RESPONDING)
-            {
-                /* Turn off the power and clock. */
-                gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvFALSE, gcvFALSE));
-
-                Hardware->clockState = gcvFALSE;
-                Hardware->powerState = gcvFALSE;
-
-                /* Wait a little. */
-                gckOS_Delay(os, 1);
-
-                /* Turn on the power and clock. */
-                gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
-
-                Hardware->clockState = gcvTRUE;
-                Hardware->powerState = gcvTRUE;
-
-                /* We need to initialize the hardware and start the command
-                 * processor. */
-                flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
-            }
-            else
-            {
-                /* Test for error. */
-                gcmkONERROR(status);
-
-                /* Break out of loop. */
-                break;
-            }
-        }
-    }
-
-    /* Get time until powered on. */
-    gcmkPROFILE_QUERY(time, onTime);
-
-    if (flag & gcvPOWER_FLAG_STALL)
-    {
-        gctBOOL idle;
-        gctINT32 atomValue;
-
-        /* For global operation, all pending commits have already been
-        ** blocked by globalSemaphore or powerSemaphore.*/
-        if (!global)
-        {
-            /* Check commit atom. */
-            gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
-
-            if (atomValue > 0)
-            {
-                /* Commits are pending - abort power management. */
-                status = broadcast ? gcvSTATUS_CHIP_NOT_READY
-                                   : gcvSTATUS_MORE_DATA;
-                goto OnError;
-            }
-        }
-
-        if (broadcast)
-        {
-            /* Check for idle. */
-            gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
-
-            if (!idle)
-            {
-                status = gcvSTATUS_CHIP_NOT_READY;
-                goto OnError;
-            }
-        }
-
-        else
-        {
-            /* Wait to finish all commands. */
-            gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
-
-            for (;;)
-            {
-                gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
-
-                if (idle)
-                {
-                    break;
-                }
-
-                gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
-            }
-        }
-    }
-
-    /* Get time until stalled. */
-    gcmkPROFILE_QUERY(time, stallTime);
-
-    if (flag & gcvPOWER_FLAG_ACQUIRE)
-    {
-        /* Acquire the power management semaphore. */
-        gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
-        acquired = gcvTRUE;
-    }
-
-    if (flag & gcvPOWER_FLAG_STOP)
-    {
-        /* Stop the command parser. */
-        gcmkONERROR(gckCOMMAND_Stop(command));
-    }
-
-    /* Flush Cache before Power Off. */
-    if (flag & gcvPOWER_FLAG_POWER_OFF)
-    {
-        if (Hardware->clockState == gcvFALSE)
-        {
-            /* Turn off the GPU power. */
-            gcmkONERROR(
-                    gckOS_SetGPUPower(os,
-                        Hardware->core,
-                        gcvTRUE,
-                        gcvTRUE));
-
-            Hardware->clockState = gcvTRUE;
-#if gcdDVFS
-            if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE)
-#endif
-            {
-                /* Write the clock control register. */
-                gcmkONERROR(gckOS_WriteRegisterEx(os,
-                                                  Hardware->core,
-                                                  0x00000,
-                                                  clocks[0]));
-
-                /* Done loading the frequency scaler. */
-                gcmkONERROR(gckOS_WriteRegisterEx(os,
-                                                  Hardware->core,
-                                                  0x00000,
-                                                  ((((gctUINT32) (clocks[0])) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
-            }
-        }
-
-        if(_IsHardwareMatch(Hardware, gcv400, 0x4645))
-        {
-            gcmkONERROR(gckCOMMAND_Start(command));
-
-            gcmkONERROR(_FlushCache(Hardware, command));
-
-            gckOS_Delay(gcvNULL, 1);
-
-            /* Stop the command parser. */
-            gcmkONERROR(gckCOMMAND_Stop(command));
-        }
-        else
-        {
-            gckHARDWARE_ExecuteFunctions(Hardware, gcvHARDWARE_FUNCTION_FLUSH);
-            gckOS_Delay(gcvNULL, 1);
-        }
-
-        flag |= gcvPOWER_FLAG_CLOCK_OFF;
-    }
-
-    /* Get time until stopped. */
-    gcmkPROFILE_QUERY(time, stopTime);
-
-    /* Only process this when hardware is enabled. */
-    if (Hardware->clockState && Hardware->powerState
-#if gcdDVFS
-    /* Don't touch clock control if dynamic frequency scaling is available. */
-    && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
-#endif
-    )
-    {
-        if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
-        {
-            if (Hardware->identity.chipModel == gcv4000
-            && ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222)))
-            {
-                clock &= ~2U;
-            }
-        }
-
-        /* Write the clock control register. */
-        gcmkONERROR(gckOS_WriteRegisterEx(os,
-                                          Hardware->core,
-                                          0x00000,
-                                          clock));
-
-        /* Done loading the frequency scaler. */
-        gcmkONERROR(gckOS_WriteRegisterEx(os,
-                                          Hardware->core,
-                                          0x00000,
-                                          ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
+                goto OnError;
+            }
+        }
+        else
+        {
+            /* Check error. */
+            gcmkONERROR(status);
+        }
+
+        /* We just check if in non-global state, but need not to acquire it. */
+        gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+        globalAcquired = gcvFALSE;
     }
 
-    if (flag & gcvPOWER_FLAG_DELAY)
+    if (Hardware->chipPowerState == gcvPOWER_ON)
     {
-        /* Wait for the specified amount of time to settle coming back from
-        ** power-off or suspend state. */
-        gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
-    }
+        /* Switch from power ON to other non-runnable states. */
+        if (broadcast)
+        {
+            gctINT32 atomValue;
 
-    /* Get time until delayed. */
-    gcmkPROFILE_QUERY(time, delayTime);
+            /* Try to acquire the semaphore to block/sync with commit. */
+            status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore);
 
-    if (flag & gcvPOWER_FLAG_INITIALIZE)
-    {
-        /* Initialize hardware. */
-        gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
+            if (gcmIS_ERROR(status))
+            {
+                status = gcvSTATUS_CHIP_NOT_READY;
+                goto OnError;
+            }
 
-        gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
-                                             Hardware->options.allowFastClear,
-                                             Hardware->options.allowCompression));
+            acquired = gcvTRUE;
 
-        /* Force the command queue to reload the next context. */
-        command->currContext = gcvNULL;
+            /* Check commit atom, abort when commit is in progress. */
+            gcmkONERROR(gckOS_AtomGet(Hardware->os,
+                                      command->atomCommit,
+                                      &atomValue));
 
-        /* Trigger a possible dummy draw. */
-        command->dummyDraw = gcvTRUE;
+            if (atomValue > 0)
+            {
+                status = gcvSTATUS_CHIP_NOT_READY;
+                goto OnError;
+            }
+        }
+        else
+        {
+            /* Acquire/wait the semaphore to block/sync with command commit. */
+            gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+            acquired = gcvTRUE;
+        }
     }
 
-    /* Get time until initialized. */
-    gcmkPROFILE_QUERY(time, initTime);
-
-    if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
+    /* Do hardware power state change. */
+    if (Hardware->chipPowerState < state)
     {
-        /* Turn off the GPU power. */
-        gcmkONERROR(
-            gckOS_SetGPUPower(os,
-                              Hardware->core,
-                              (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
-                                                               : gcvTRUE,
-                              (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
-                                                               : gcvTRUE));
-
-        /* Save current hardware power and clock states. */
-        Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
-                                                                : gcvTRUE;
-        Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
-                                                                : gcvTRUE;
+        /* On to off direction. */
+        gcmkONERROR(_PmSetPowerOffDirection(Hardware, state, broadcast));
     }
-
-    /* Get time until off. */
-    gcmkPROFILE_QUERY(time, offTime);
-
-    if (flag & gcvPOWER_FLAG_START)
+    else
     {
-        /* Start the command processor. */
-        gcmkONERROR(gckCOMMAND_Start(command));
-
-        commandStarted = gcvTRUE;
+        /* Off to on direction. */
+        gcmkONERROR(_PmSetPowerOnDirection(Hardware, state));
     }
 
-    /* Get time until started. */
-    gcmkPROFILE_QUERY(time, startTime);
+    if (status == gcvSTATUS_CHIP_NOT_READY)
+    {
+        /* CHIP_NOT_READY is not an error, either not success. */
+        goto OnError;
+    }
 
-    if (flag & gcvPOWER_FLAG_RELEASE)
+    if (state == gcvPOWER_ON)
     {
-        /* Release the power management semaphore. */
+        /* Switched to power ON from other non-runnable states. */
         gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
         acquired = gcvFALSE;
 
         if (global)
         {
-            /* Verify global semaphore has been acquired already before
-            ** we release it.
-            ** If it was acquired, gckOS_TryAcquireSemaphore will return
-            ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
-            ** semaphore will be acquried now, but it still is released
-            ** immediately. */
+            /*
+             * Global semaphore should be acquired already before, when
+             * global OFF, IDLE or SUSPEND.
+             */
             status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
-            if (status != gcvSTATUS_TIMEOUT)
+            if (status != gcvSTATUS_TIMEOUT && Hardware->isLastPowerGlobal)
             {
-                gcmkONERROR(status);
+                gcmkPRINT("%s: global state error", __FUNCTION__);
             }
 
-            /* Release the global semaphore. */
+            /* Switched to global ON, now release the global semaphore. */
             gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
             globalAcquired = gcvFALSE;
         }
     }
 
-    gckSTATETIMER_Accumulate(&Hardware->powerStateCounter, Hardware->chipPowerState);
+    gckSTATETIMER_Accumulate(&Hardware->powerStateCounter,
+                             Hardware->chipPowerState);
 
     /* Save the new power state. */
-    Hardware->chipPowerState = State;
+    Hardware->chipPowerState = state;
+    Hardware->isLastPowerGlobal = global;
 
 #if gcdDVFS
-    if (State == gcvPOWER_ON && Hardware->kernel->dvfs)
+    if (state == gcvPOWER_ON && Hardware->kernel->dvfs)
     {
         gckDVFS_Start(Hardware->kernel->dvfs);
     }
 #endif
 
-#if gcdPOWEROFF_TIMEOUT
-    /* Reset power off time */
-    gcmkONERROR(gckOS_GetTicks(&currentTime));
-
-    Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
-
-    if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+    if (!broadcast)
     {
-        /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
-        gcmkVERIFY_OK(gckOS_StartTimer(os,
-                                       Hardware->powerOffTimer,
-                                       Hardware->powerOffTimeout));
+        /*
+         * Cancel delayed power state change.
+         * Stop timer is not as good as set as no state change. Timer may run
+         * into this function already when try to to stop the timer.
+         */
+        Hardware->nextPowerState = gcvPOWER_INVALID;
     }
-    else
+
+#if gcdPOWEROFF_TIMEOUT
+    if (state == gcvPOWER_IDLE || state == gcvPOWER_SUSPEND)
     {
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
+        /* Delayed power off. */
+        Hardware->nextPowerState = gcvPOWER_OFF_TIMEOUT;
 
-        /* Cancel running timer when GPU enters ON or OFF. */
-        gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
+        /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
+        gcmkVERIFY_OK(gckOS_StartTimer(os, Hardware->powerStateTimer, gcdPOWEROFF_TIMEOUT));
     }
 #endif
 
     /* Release the power mutex. */
     gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
 
-    /* Get total time. */
-    gcmkPROFILE_QUERY(time, totalTime);
-#if gcdENABLE_PROFILING
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                   "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
-                   freq, mutexTime, onTime, stallTime, stopTime);
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                   "  delay:%llu init:%llu off:%llu start:%llu total:%llu",
-                   delayTime, initTime, offTime, startTime, totalTime);
-#endif
-
     /* Success. */
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (commandStarted)
-    {
-        gcmkVERIFY_OK(gckCOMMAND_Stop(command));
-    }
-
     if (acquired)
     {
         /* Release semaphore. */
@@ -10535,11 +10004,10 @@ OnError:
     gcmkFOOTER();
     return status;
 }
-#endif
 
 /*******************************************************************************
 **
-**  gckHARDWARE_QueryPowerManagementState
+**  gckHARDWARE_QueryPowerState
 **
 **  Get GPU power state.
 **
@@ -10553,7 +10021,7 @@ OnError:
 **
 */
 gceSTATUS
-gckHARDWARE_QueryPowerManagementState(
+gckHARDWARE_QueryPowerState(
     IN gckHARDWARE Hardware,
     OUT gceCHIPPOWERSTATE* State
     )
@@ -10574,7 +10042,7 @@ gckHARDWARE_QueryPowerManagementState(
 
 /*******************************************************************************
 **
-**  gckHARDWARE_SetPowerManagement
+**  gckHARDWARE_EnablePowerManagement
 **
 **  Configure GPU power management function.
 **  Only used in driver initialization stage.
@@ -10584,14 +10052,14 @@ gckHARDWARE_QueryPowerManagementState(
 **      gckHARDWARE Harwdare
 **          Pointer to an gckHARDWARE object.
 **
-**      gctBOOL PowerManagement
-**          Power Mangement State.
+**      gctBOOL Enable
+**          Power Mangement Enabling State.
 **
 */
 gceSTATUS
-gckHARDWARE_SetPowerManagement(
+gckHARDWARE_EnablePowerManagement(
     IN gckHARDWARE Hardware,
-    IN gctBOOL PowerManagement
+    IN gctBOOL Enable
     )
 {
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
@@ -10602,7 +10070,7 @@ gckHARDWARE_SetPowerManagement(
     gcmkVERIFY_OK(
         gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
 
-    Hardware->options.powerManagement = PowerManagement;
+    Hardware->options.powerManagement = Enable;
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
 
@@ -10946,39 +10414,6 @@ gckHARDWARE_SetMinFscaleValue(
 }
 #endif
 
-#if !gcdPOWER_MANAGEMENT_REFINEMENT
-#if gcdPOWEROFF_TIMEOUT
-gceSTATUS
-gckHARDWARE_SetPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    IN gctUINT32    Timeout
-)
-{
-    gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
-
-    Hardware->powerOffTimeout = Timeout;
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-
-gceSTATUS
-gckHARDWARE_QueryPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    OUT gctUINT32*  Timeout
-)
-{
-    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
-
-    *Timeout = Hardware->powerOffTimeout;
-
-    gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
-    return gcvSTATUS_OK;
-}
-#endif
-#endif
-
 gceSTATUS
 gckHARDWARE_QueryIdle(
     IN gckHARDWARE Hardware,
@@ -11278,7 +10713,7 @@ gckHARDWARE_UpdateContextProfile(
     gctUINT32 chipRevision;
     gctUINT32 i;
     gctUINT32 resetValue = 0xF;
-    gctBOOL hasNewCounters = gcvFALSE;
+    gctBOOL newCounters0 = gcvFALSE;
     gctUINT32 clock;
     gctUINT32 colorKilled = 0, colorDrawn = 0, depthKilled = 0, depthDrawn = 0;
     gctUINT32 totalRead, totalWrite;
@@ -11304,9 +10739,8 @@ gckHARDWARE_UpdateContextProfile(
     if ((chipModel == gcv5000 && chipRevision == 0x5434) || (chipModel == gcv3000 && chipRevision == 0x5435))
     {
         resetValue = 0xFF;
-        hasNewCounters = gcvTRUE;
+        newCounters0 = gcvTRUE;
     }
-
     if (chipModel == gcv2100 || chipModel == gcv2000 || chipModel == gcv880)
     {
         gcmkONERROR(
@@ -11737,7 +11171,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile
  31:24) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler_part1->ps_texld_inst_counter));
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:24) - (0 ?
@@ -11892,7 +11326,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile
     gcmkRESET_PROFILE_DATA_PART1(vs_texld_inst_counter);
     gcmkRESET_PROFILE_DATA_PART1(ps_branch_inst_counter);
     gcmkRESET_PROFILE_DATA_PART1(ps_texld_inst_counter);
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkRESET_PROFILE_DATA_PART1(vs_non_idle_starve_count);
         gcmkRESET_PROFILE_DATA_PART1(vs_starve_count);
@@ -11917,7 +11351,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile
     gcmkUPDATE_PROFILE_DATA_PART1(vs_texld_inst_counter);
     gcmkUPDATE_PROFILE_DATA_PART1(ps_branch_inst_counter);
     gcmkUPDATE_PROFILE_DATA_PART1(ps_texld_inst_counter);
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkUPDATE_PROFILE_DATA_PART1(vs_non_idle_starve_count);
         gcmkUPDATE_PROFILE_DATA_PART1(vs_starve_count);
@@ -12046,7 +11480,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profile
  7:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler_part1->pa_frustum_clipped_prim_counter));
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  7:0) - (0 ?
@@ -12102,7 +11536,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profile
     gcmkRESET_PROFILE_DATA_PART1(pa_culled_prim_counter);
     gcmkRESET_PROFILE_DATA_PART1(pa_droped_prim_counter);
     gcmkRESET_PROFILE_DATA_PART1(pa_frustum_clipped_prim_counter);
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkRESET_PROFILE_DATA_PART1(pa_non_idle_starve_count);
         gcmkRESET_PROFILE_DATA_PART1(pa_starve_count);
@@ -12118,7 +11552,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profile
     gcmkUPDATE_PROFILE_DATA_PART1(pa_culled_prim_counter);
     gcmkUPDATE_PROFILE_DATA_PART1(pa_droped_prim_counter);
     gcmkUPDATE_PROFILE_DATA_PART1(pa_frustum_clipped_prim_counter);
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkUPDATE_PROFILE_DATA_PART1(pa_non_idle_starve_count);
         gcmkUPDATE_PROFILE_DATA_PART1(pa_starve_count);
@@ -12204,7 +11638,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profile
  15:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler_part1->se_trivial_rejected_line_count));
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:8) - (0 ?
@@ -12322,7 +11756,7 @@ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((g
     gcmkUPDATE_PROFILE_DATA_PART1(se_culled_triangle_count);
     gcmkUPDATE_PROFILE_DATA_PART1(se_culled_lines_count);
     gcmkUPDATE_PROFILE_DATA_PART1(se_trivial_rejected_line_count);
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkUPDATE_PROFILE_DATA_PART1(se_starve_count);
         gcmkUPDATE_PROFILE_DATA_PART1(se_stall_count);
@@ -12434,7 +11868,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profile
  23:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler_part1->ra_prefetch_hz_cache_miss_counter));
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  23:16) - (0 ?
@@ -12491,7 +11925,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profile
     gcmkRESET_PROFILE_DATA_PART1(ra_eez_culled_counter);
     gcmkRESET_PROFILE_DATA_PART1(ra_pipe_hz_cache_miss_counter);
     gcmkRESET_PROFILE_DATA_PART1(ra_prefetch_hz_cache_miss_counter);
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkRESET_PROFILE_DATA_PART1(ra_non_idle_starve_count);
         gcmkRESET_PROFILE_DATA_PART1(ra_starve_count);
@@ -12508,7 +11942,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profile
     gcmkUPDATE_PROFILE_DATA_PART1(ra_eez_culled_counter);
     gcmkUPDATE_PROFILE_DATA_PART1(ra_pipe_hz_cache_miss_counter);
     gcmkUPDATE_PROFILE_DATA_PART1(ra_prefetch_hz_cache_miss_counter);
-    if (hasNewCounters)
+    if (newCounters0)
     {
         gcmkUPDATE_PROFILE_DATA_PART1(ra_non_idle_starve_count);
         gcmkUPDATE_PROFILE_DATA_PART1(ra_starve_count);
@@ -12967,7 +12401,7 @@ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((g
     gcmkUPDATE_PROFILE_DATA_PART2(mc_sh1_write_bandwidth);
 
     /* read latency counters */
-    if (hasNewCounters)
+    if (newCounters0)
     {
         /* latency */
         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
@@ -13444,7 +12878,7 @@ _ResetGPU(
 
 #if gcdFPGA_BUILD
         /* Wait more time on FPGA for reset as lower frequency */
-        gcmkONERROR(gckOS_Delay(Os, 3));
+        gcmkONERROR(gckOS_Delay(Os, 10));
 #else
         /* Wait for reset. */
         gcmkONERROR(gckOS_Delay(Os, 1));
@@ -13807,6 +13241,10 @@ gckHARDWARE_DumpMMUException(
     gctUINT32 offset    = 0;
     gctUINT32 mmuStatusRegAddress;
     gctUINT32 mmuExceptionAddress;
+    gceAREA_TYPE areaType = gcvAREA_TYPE_UNKNOWN;
+    gctUINT32 stlbShift;
+    gctUINT32 stlbMask;
+    gctUINT32 pgoffMask;
 
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
 
@@ -13894,15 +13332,39 @@ gckHARDWARE_DumpMMUException(
               gcmkPRINT("  MMU%d: unknown state\n", i);
         }
 
-        gcmkVERIFY_OK(
-            gckOS_ReadRegisterEx(Hardware->os,
-                                 Hardware->core,
-                                 mmuExceptionAddress + i * 4,
-                                 &address));
+        if (Hardware->options.secureMode == gcvSECURE_NONE)
+        {
+            gcmkVERIFY_OK(
+                gckOS_ReadRegisterEx(Hardware->os,
+                                     Hardware->core,
+                                     mmuExceptionAddress + i * 4,
+                                     &address));
+        }
+        else
+        {
+            gcmkVERIFY_OK(
+                gckOS_ReadRegisterEx(Hardware->os,
+                                     Hardware->core,
+                                     mmuExceptionAddress,
+                                     &address));
+        }
+
+        gckMMU_GetAreaType(Hardware->kernel->mmu, address, &areaType);
+
+        if (areaType == gcvAREA_TYPE_UNKNOWN)
+        {
+            gcmkPRINT("  MMU%d: exception address = 0x%08X, it is not mapped.\n", i, address);
+            gcmkFOOTER_NO();
+            return gcvSTATUS_OK;
+        }
+
+        pgoffMask = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_OFFSET_4K_MASK : gcdMMU_OFFSET_1M_MASK;
+        stlbShift = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_STLB_4K_SHIFT : gcdMMU_STLB_1M_SHIFT;
+        stlbMask  = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_STLB_4K_MASK : gcdMMU_STLB_1M_MASK;
 
         mtlb   = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
-        stlb   = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
-        offset =  address & gcdMMU_OFFSET_4K_MASK;
+        stlb   = (address & stlbMask) >> stlbShift;
+        offset =  address & pgoffMask;
 
         gcmkPRINT("  MMU%d: exception address = 0x%08X\n", i, address);
 
@@ -13912,7 +13374,7 @@ gckHARDWARE_DumpMMUException(
 
         gcmkPRINT("    Offset = 0x%08X (%d)\n", offset, offset);
 
-        gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
+        gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, areaType, address);
 
         gckMMU_DumpRecentFreedAddress(Hardware->kernel->mmu);
     }
@@ -13987,8 +13449,20 @@ gckHARDWARE_HandleFault(
         gckVIDMEM_NODE nodeObject = gcvNULL;
         gctUINT32 offset = 0;
         gctPHYS_ADDR_T physicalAddress = 0;
+        gceAREA_TYPE areaType;
+        gctUINT32 pageMask;
+        gcePAGE_TYPE pageType;
 
+        gckMMU_GetAreaType(Hardware->kernel->mmu, address, &areaType);
+
+        pageMask = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_PAGE_4K_MASK : gcdMMU_PAGE_1M_MASK;
+        pageType = (areaType == gcvAREA_TYPE_4K) ? gcvPAGE_TYPE_4K : gcvPAGE_TYPE_1M;
+
+#if gcdENABLE_TRUST_APPLICATION
         address &= ~gcdMMU_PAGE_4K_MASK;
+#else
+        address &= ~pageMask;
+#endif
 
         /* Try to allocate memory and setup map for exception address. */
         gcmkONERROR(gckVIDMEM_NODE_Find(
@@ -14021,9 +13495,9 @@ gckHARDWARE_HandleFault(
             gctUINT32_PTR entry;
 
             /* Setup page table. */
-            gcmkONERROR(gckMMU_GetPageEntry(Hardware->kernel->mmu, address, &entry));
+            gcmkONERROR(gckMMU_GetPageEntry(Hardware->kernel->mmu, pageType, address, &entry));
 
-            gckMMU_SetPage(Hardware->kernel->mmu, physicalAddress, gcvTRUE, entry);
+            gckMMU_SetPage(Hardware->kernel->mmu, physicalAddress, pageType, gcvTRUE, entry);
 
             /* Resume hardware execution. */
             gcmkVERIFY_OK(gckOS_WriteRegisterEx(
@@ -14207,8 +13681,33 @@ gckHARDWARE_DumpGPUState(
         "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST", "INVALID_VER_ST"
     };
 
+    enum
+    {
+        RA_INDEX      = 0,
+        TX_INDEX      = 1,
+        FE_INDEX      = 2,
+        PE_INDEX      = 3,
+        DE_INDEX      = 4,
+        SH_INDEX      = 5,
+        PA_INDEX      = 6,
+        SE_INDEX      = 7,
+        MC_INDEX      = 8,
+        HI_INDEX      = 9,
+        TPG_INDEX     = 10,
+        TFB_INDEX     = 11,
+        USC_INDEX     = 12,
+        L2_INDEX      = 13,
+        BLT_INDEX     = 14,
+        WD_INDEX      = 15,
+        VTXDATA_INDEX = 16,
+        DIR_INDEX     = 17,
+        PPA_INDEX     = 18,
+        NN_INDEX      = 19,
+        MODULE_MAX_INDEX,
+    };
+
     /* must keep order correctly for _dbgRegs, we need ajust some value base on the index */
-    static gcsiDEBUG_REGISTERS _dbgRegs[] =
+    static gcsiDEBUG_REGISTERS _dbgRegs[MODULE_MAX_INDEX] =
     {
         { "RA", 0x474, 16, 0x448, 256, 0x1, 0x00, gcvTRUE, gcvTRUE  },
         { "TX", 0x474, 24, 0x44C, 128, 0x1, 0x00, gcvTRUE, gcvTRUE  },
@@ -14226,7 +13725,11 @@ gckHARDWARE_DumpGPUState(
         { "L2", 0x478, 0, 0x564, 256, 0x1, 0x00, gcvTRUE, gcvFALSE },
         { "BLT", 0x478, 24, 0x1A4, 256, 0x1, 0x00, gcvFALSE, gcvTRUE  },
         { "WD", 0xF0, 16, 0xF4, 256, 0x1, 0x00, gcvFALSE, gcvFALSE },
+        { "VTXDATA", 0x474, 24, 0x44C, 64, 0x1, 0x40, gcvFALSE, gcvTRUE  },
+        { "DIR", 0xF0, 24, 0xF8, 256, 0x1, 0x00, gcvFALSE, gcvTRUE  },
+        { "PPA", 0x474, 0, 0x598, 256, 0x1, 0x00, gcvFALSE, gcvTRUE  },
         { "NN", 0x474, 24, 0x44C, 256, 0x2, 0x00, gcvFALSE, gcvTRUE  },
+
     };
 
     static gctUINT32 _otherRegs[] =
@@ -14243,7 +13746,8 @@ gckHARDWARE_DumpGPUState(
     gctUINT32 cmdState = 0, cmdDmaState = 0, cmdFetState = 0;
     gctUINT32 dmaReqState = 0, calState = 0, veReqState = 0;
     gctUINT i;
-    gctUINT pipe = 0, pixelPipes = 0;
+    gctUINT pipe = 0, pipeMask = 0x1;
+    static const gctUINT maxNumOfPipes = 4;
     gctUINT32 control = 0, oldControl = 0;
     gckOS os = Hardware->os;
     gceCORE core = Hardware->core;
@@ -14261,16 +13765,23 @@ gckHARDWARE_DumpGPUState(
                 Hardware->identity.chipModel,
                 Hardware->identity.chipRevision);
 
-    pixelPipes = Hardware->identity.pixelPipes
-               ? Hardware->identity.pixelPipes
-               : 1;
-
     /* Reset register values. */
     idle        = axi         =
     dmaState1   = dmaState2   =
     dmaAddress1 = dmaAddress2 =
     dmaLow      = dmaHigh     = 0;
 
+    switch (Hardware->identity.pixelPipes)
+    {
+    case 2:
+        pipeMask = 0x3;
+        break;
+    case 1:
+        pipeMask = 0x1;
+        break;
+    default:
+        gcmkASSERT(0);
+    }
     /* Verify whether DMA is running. */
     gcmkONERROR(_VerifyDMA(
         os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
@@ -14315,12 +13826,12 @@ gckHARDWARE_DumpGPUState(
     if ((idle & 0x00008000) == 0) gcmkPRINT_N(0, "    PPA not idle\n");
     if ((idle & 0x00010000) == 0) gcmkPRINT_N(0, "    DC not idle\n");
     if ((idle & 0x00020000) == 0) gcmkPRINT_N(0, "    WD not idle\n");
+    if ((idle & 0x00040000) == 0) gcmkPRINT_N(0, "    NN not idle\n");
+    if ((idle & 0x00080000) == 0) gcmkPRINT_N(0, "    TP not idle\n");
     if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, "    AXI low power mode\n");
 
-    if (
-        (dmaAddress1 == dmaAddress2)
-     && (dmaState1 == dmaState2)
-    )
+    if ((dmaAddress1 == dmaAddress2)
+     && (dmaState1 == dmaState2))
     {
         gcmkPRINT_N(0, "  DMA appears to be stuck at this address:\n");
         gcmkPRINT_N(4, "    0x%08X\n", dmaAddress1);
@@ -14355,25 +13866,30 @@ gckHARDWARE_DumpGPUState(
 
     if (bltEngine)
     {
-        _dbgRegs[14].avail = gcvTRUE;
+        _dbgRegs[BLT_INDEX].avail = gcvTRUE;
     }
     if (hwTFB)
     {
-        _dbgRegs[11].avail = gcvTRUE;
+        _dbgRegs[TFB_INDEX].avail = gcvTRUE;
     }
     if (usc)
     {
-        _dbgRegs[12].avail = gcvTRUE;
+        _dbgRegs[USC_INDEX].avail = gcvTRUE;
     }
     if (gsShader)
     {
-        _dbgRegs[10].avail = gcvTRUE;
+        _dbgRegs[TPG_INDEX].avail = gcvTRUE;
     }
     if (multiCluster)
     {
-        _dbgRegs[15].avail = gcvTRUE;
-        _dbgRegs[2].index = 0xF0;
-        _dbgRegs[9].index = 0xF0;
+        _dbgRegs[WD_INDEX].avail = gcvTRUE;
+        _dbgRegs[DIR_INDEX].avail = gcvTRUE;
+        _dbgRegs[VTXDATA_INDEX].avail = gcvTRUE;
+        _dbgRegs[PPA_INDEX].avail = gcvTRUE;
+        _dbgRegs[FE_INDEX].index = 0xF0;
+        _dbgRegs[HI_INDEX].index = 0xF0;
+        /*spare 64 DWORDS debug values from TX for VTXDATA prefetch in USC */
+        _dbgRegs[TX_INDEX].count = 64;
 
         for (i = 0; i < gcmCOUNTOF(_dbgRegs); i++)
         {
@@ -14383,10 +13899,11 @@ gckHARDWARE_DumpGPUState(
                     Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask;
             }
         }
+        pipeMask = Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask;
     }
     if (nnEngine)
     {
-        _dbgRegs[16].avail = gcvTRUE;
+        _dbgRegs[NN_INDEX].avail = gcvTRUE;
     }
 
     for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
@@ -14395,10 +13912,13 @@ gckHARDWARE_DumpGPUState(
     }
 
     /* Record control. */
-    gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
+    gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x0, &oldControl));
 
-    for (pipe = 0; pipe < pixelPipes; pipe++)
+    for (pipe = 0; pipe < maxNumOfPipes; pipe++)
     {
+        if (((1 << pipe) & pipeMask) == 0)
+            continue;
+
         gcmkPRINT_N(4, "    Other Registers[%d]:\n", pipe);
 
         /* Switch pipe. */
@@ -14414,12 +13934,11 @@ gckHARDWARE_DumpGPUState(
             gcmkPRINT_N(12, "      [0x%04X] 0x%08X\n", _otherRegs[i], read);
         }
 
-        if (Hardware->mmuVersion)
-        {
-            gcmkPRINT("    MMU status from MC[%d]:", pipe);
-
-            gckHARDWARE_DumpMMUException(Hardware);
-        }
+         if (Hardware->mmuVersion)
+         {
+             gcmkPRINT("    MMU status from MC[%d]:", pipe);
+             gckHARDWARE_DumpMMUException(Hardware);
+         }
     }
 
     /* MCFE state. */
@@ -14431,6 +13950,7 @@ gckHARDWARE_DumpGPUState(
     /* Restore control. */
     gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, oldControl));
 
+
     if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI0))
     {
         /* FE debug register. */
@@ -15264,11 +14784,7 @@ _PrepareFunctions(
         mode = gcvMMU_MODE_4K;
 #endif
 
-#if defined(CONFIG_ZONE_DMA32)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
         flags |= gcvALLOC_FLAG_4GB_ADDR;
-#endif
-#endif
 
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
         flags |= gcvALLOC_FLAG_CACHEABLE;
@@ -17679,57 +17195,47 @@ gckHARDWARE_DummyDraw(
  4:4) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))),
 
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
         /* SubmitJob. */
         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))),
         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))),
         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))),
         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
-#  endif
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))),
     };
 
     gctUINT32 bytes = 0;
@@ -17746,35 +17252,30 @@ gckHARDWARE_DummyDraw(
     case gcvDUMMY_DRAW_V60:
         dummyDraw = dummyDraw_v60;
         bytes = gcmSIZEOF(dummyDraw_v60);
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
         if (_QueryFeatureDatabase(Hardware, gcvFEATURE_MCFE))
         {
             gctUINT32 submitJob;
 
             submitJob = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x16 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_SUBMIT_JOB & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)));
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) (0x001 & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
             if (bytes & 8)
             {
@@ -17784,7 +17285,6 @@ gckHARDWARE_DummyDraw(
 
             dummyDraw[(bytes >> 2) - 2] = submitJob;
         }
-#  endif
         break;
     default:
         /* other chip no need dummy draw.*/
@@ -17906,6 +17406,8 @@ gckHARDWARE_QueryFrequency(
     gctUINT32 mcClk, shClk;
     gceSTATUS status;
     gctUINT64 powerManagement = 0;
+    gctBOOL globalAcquired = gcvFALSE;
+    gceCHIPPOWERSTATE statesStored, state;
 
     gcmkHEADER_ARG("Hardware=0x%p", Hardware);
 
@@ -17914,36 +17416,40 @@ gckHARDWARE_QueryFrequency(
     mcStart = shStart = 0;
     mcClk   = shClk   = 0;
 
-    gckOS_QueryOption(Hardware->os, "powerManagement", &powerManagement);
+    status = gckOS_QueryOption(Hardware->os, "powerManagement", &powerManagement);
+    if (gcmIS_ERROR(status))
+    {
+        powerManagement = 0;
+    }
 
     if (powerManagement)
     {
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
             Hardware, gcvFALSE
             ));
     }
 
-    gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+    gcmkONERROR(gckHARDWARE_QueryPowerState(
+        Hardware, &statesStored
+        ));
+
+    gcmkONERROR(gckHARDWARE_SetPowerState(
         Hardware, gcvPOWER_ON_AUTO
         ));
 
+    /* Grab the global semaphore. */
+    gcmkONERROR(gckOS_AcquireSemaphore(
+        Hardware->os, Hardware->globalSemaphore
+        ));
+
+    globalAcquired = gcvTRUE;
+
     gckHARDWARE_EnterQueryClock(Hardware, &mcStart, &shStart);
 
     gcmkONERROR(gckOS_Delay(Hardware->os, 50));
 
     if (mcStart)
     {
-        if (powerManagement)
-        {
-            gcmkONERROR(gckHARDWARE_SetPowerManagement(
-                Hardware, gcvFALSE
-                ));
-        }
-
-        gcmkONERROR(gckHARDWARE_SetPowerManagementState(
-            Hardware, gcvPOWER_ON_AUTO
-            ));
-
         gckHARDWARE_ExitQueryClock(Hardware,
                                    mcStart, shStart,
                                    &mcClk, &shClk);
@@ -17952,18 +17458,56 @@ gckHARDWARE_QueryFrequency(
         Hardware->shClk = shClk;
     }
 
+    /* Release the global semaphore. */
+    gcmkONERROR(gckOS_ReleaseSemaphore(
+        Hardware->os, Hardware->globalSemaphore
+        ));
+
+    globalAcquired = gcvFALSE;
+
+    switch(statesStored)
+    {
+    case gcvPOWER_OFF:
+        state = gcvPOWER_OFF_BROADCAST;
+        break;
+    case gcvPOWER_IDLE:
+        state = gcvPOWER_IDLE_BROADCAST;
+        break;
+    case gcvPOWER_SUSPEND:
+        state = gcvPOWER_SUSPEND_BROADCAST;
+        break;
+    case gcvPOWER_ON:
+        state = gcvPOWER_ON_AUTO;
+        break;
+    default:
+        state = statesStored;
+        break;
+    }
+
     if (powerManagement)
     {
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
             Hardware, gcvTRUE
             ));
     }
 
+    gcmkONERROR(gckHARDWARE_SetPowerState(
+        Hardware, state
+        ));
+
     gcmkFOOTER_NO();
 
     return gcvSTATUS_OK;
 
 OnError:
+    if (globalAcquired)
+    {
+        /* Release the global semaphore. */
+        gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
+            Hardware->os, Hardware->globalSemaphore
+            ));
+    }
+
     gcmkFOOTER();
 
     return status;
index d518d101bb13b8af707b17e11e72b450b49aac02..1ae9edfc701bebf63b7094f9937181dd9f0e634d 100644 (file)
@@ -61,8 +61,6 @@
 extern "C" {
 #endif
 
-#define gcdPOWER_MANAGEMENT_REFINEMENT  1
-
 #define EVENT_ID_INVALIDATE_PIPE    29
 
 typedef enum {
@@ -192,14 +190,11 @@ struct _gckHARDWARE
 
     /* Chip status */
     gctPOINTER                  powerMutex;
-#if !gcdPOWER_MANAGEMENT_REFINEMENT
-    gctUINT32                   powerProcess;
-    gctUINT32                   powerThread;
-#endif
     gceCHIPPOWERSTATE           chipPowerState;
     gctBOOL                     clockState;
     gctBOOL                     powerState;
     gctPOINTER                  globalSemaphore;
+    gctBOOL                     isLastPowerGlobal;
 
     /* Wait Link FE only. */
     gctUINT32                   lastWaitLink;
@@ -207,18 +202,9 @@ struct _gckHARDWARE
 
     gctUINT32                   mmuVersion;
 
-#if gcdPOWER_MANAGEMENT_REFINEMENT
     gceCHIPPOWERSTATE           nextPowerState;
     gctPOINTER                  powerStateTimer;
 
-#else
-#if gcdPOWEROFF_TIMEOUT
-    gctUINT32                   powerOffTime;
-    gctUINT32                   powerOffTimeout;
-    gctPOINTER                  powerOffTimer;
-#endif
-#endif
-
 #if gcdENABLE_FSCALE_VAL_ADJUST
     gctUINT32                   powerOnFscaleVal;
 #endif
@@ -256,11 +242,9 @@ struct _gckHARDWARE
     /* Head for hardware list in gckMMU. */
     gcsLISTHEAD                 mmuHead;
 
-    /* SRAM mode. */
-    gctUINT32                   sRAMNonExclusive;
-    gckVIDMEM                   sRAMVideoMem[gcvSRAM_COUNT];
-    gctPHYS_ADDR                sRAMPhysical[gcvSRAM_COUNT];
-    gctPOINTER                  sRAMLogical[gcvSRAM_COUNT];
+    /* Internal SRAMs info. */
+    gckVIDMEM                   sRAMVidMem[gcvSRAM_INTER_COUNT];
+    gctPHYS_ADDR                sRAMPhysical[gcvSRAM_INTER_COUNT];
 
     gctPOINTER                  featureDatabase;
     gctBOOL                     hasL2Cache;
index bfebefd7b0c6e21abae8c839b29aa0e3c4a5f5cb..40672cf144998e220724d244b7c940c0b785a427 100644 (file)
@@ -98,7 +98,7 @@ gckASYNC_FE_Construct(
     gcmkONERROR(gckOS_AtomSet(Hardware->os, fe->freeDscriptors, data));
 
     /* Enable interrupts. */
-    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x000D8, ~0U);
+    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x000D8, ~0U));
 
     *FE = fe;
 
@@ -106,9 +106,13 @@ gckASYNC_FE_Construct(
     return gcvSTATUS_OK;
 
 OnError:
-    if (fe->freeDscriptors)
+    if (fe)
     {
-        gckOS_AtomDestroy(Hardware->os, fe->freeDscriptors);
+        if (fe->freeDscriptors)
+        {
+            gckOS_AtomDestroy(Hardware->os, fe->freeDscriptors);
+        }
+        gcmkOS_SAFE_FREE(Hardware->os, fe);
     }
 
     gcmkFOOTER();
@@ -632,24 +636,34 @@ gckASYNC_FE_Execute(
     IN gctUINT32 Bytes
     )
 {
-    gckOS_WriteRegisterEx(
+    gceSTATUS status;
+
+    status = gckOS_WriteRegisterEx(
         Hardware->os,
         Hardware->core,
         0x007DC,
         Address
         );
+    if (gcmIS_ERROR(status))
+    {
+        return status;
+    }
 
     gckOS_MemoryBarrier(
         Hardware->os,
         gcvNULL
         );
 
-    gckOS_WriteRegisterEx(
+    status = gckOS_WriteRegisterEx(
         Hardware->os,
         Hardware->core,
         0x007E0,
         Address + Bytes
         );
+    if (gcmIS_ERROR(status))
+    {
+        return status;
+    }
 
     return gcvSTATUS_OK;
 }
index f652204dd2e70f98a7c2adbafd94a321f160bcad..76d9cf87f7d1c7285eef28c4dceffe9e4353ff4a 100644 (file)
@@ -317,7 +317,6 @@ _ProgramDescRingBuf(
     IN gctBOOL Priority
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gctUINT32 ringBufStartReg;
     gctUINT32 depthExpReg;
     gctUINT32 readPtrReg;
@@ -326,17 +325,17 @@ _ProgramDescRingBuf(
 
     if (Priority)
     {
-        ringBufStartReg = GCREG_MCFE_PRI_DESC_RING_BUF_START_ADDR_Address;
-        depthExpReg     = GCREG_MCFE_PRI_DESC_FIFO_DEPTH_EXP_Address;
-        readPtrReg      = GCREG_MCFE_PRI_DESC_FIFO_RD_PTR_Address;
-        writePtrReg     = GCREG_MCFE_PRI_DESC_FIFO_WR_PTR_Address;
+        ringBufStartReg = 0x02800;
+        depthExpReg     = 0x02900;
+        readPtrReg      = 0x02B00;
+        writePtrReg     = 0x02A00;
     }
     else
     {
-        ringBufStartReg = GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address;
-        depthExpReg     = GCREG_MCFE_STD_DESC_FIFO_DEPTH_EXP_Address;
-        readPtrReg      = GCREG_MCFE_STD_DESC_FIFO_RD_PTR_Address;
-        writePtrReg     = GCREG_MCFE_STD_DESC_FIFO_WR_PTR_Address;
+        ringBufStartReg = 0x02400;
+        depthExpReg     = 0x02500;
+        readPtrReg      = 0x02700;
+        writePtrReg     = 0x02600;
     }
 
     ringBufStartReg += Index << 2;
@@ -365,9 +364,6 @@ _ProgramDescRingBuf(
     Channel->readPtr = Channel->writePtr = data;
 
     return gcvSTATUS_OK;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 static gceSTATUS
@@ -439,7 +435,6 @@ gckMCFE_Nop(
     IN OUT gctSIZE_T * Bytes
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
     gceSTATUS status;
 
@@ -460,29 +455,25 @@ gckMCFE_Nop(
 
         /* Append NOP. */
         logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
         logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
     }
@@ -501,9 +492,6 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 
@@ -516,7 +504,6 @@ gckMCFE_Event(
     IN OUT gctUINT32 * Bytes
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gctUINT size;
     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
     gceSTATUS status;
@@ -544,43 +531,37 @@ gckMCFE_Event(
 
         /* Append EVENT(Event). */
         logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x16 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
MCFE_COMMAND_SUB_OPCODE) - (0 ?
MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
25:16) - (0 ?
25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_INTERRUPT_EVENT & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)))
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) (0x006 & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
                    | Event;
 
         logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
         {
@@ -614,9 +595,6 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 gceSTATUS
@@ -627,7 +605,6 @@ gckMCFE_SendSemaphore(
     IN OUT gctUINT32 * Bytes
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
     gceSTATUS status;
 
@@ -649,43 +626,37 @@ gckMCFE_SendSemaphore(
 
         /* Append SEND_SEMAPHORE(SemaId). */
         logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x16 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
MCFE_COMMAND_SUB_OPCODE) - (0 ?
MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
25:16) - (0 ?
25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_SEND_SEMAPHORE & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)))
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) (0x002 & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
                    | SemaId;
 
         logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
     }
 
     if (Bytes != gcvNULL)
@@ -701,9 +672,6 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 gceSTATUS
@@ -714,7 +682,6 @@ gckMCFE_WaitSemaphore(
     IN OUT gctUINT32 * Bytes
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
     gceSTATUS status;
 
@@ -736,43 +703,37 @@ gckMCFE_WaitSemaphore(
 
         /* Append WAIT_SEMAPHORE(SemaId). */
         logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x16 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
MCFE_COMMAND_SUB_OPCODE) - (0 ?
MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
25:16) - (0 ?
25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_WAIT_SEMAPHORE & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_SUB_OPCODE) - (0 ?
- MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)))
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) (0x003 & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
                    | SemaId;
 
         logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
- MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- MCFE_COMMAND_OPCODE) - (0 ?
- MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
     }
 
     if (Bytes != gcvNULL)
@@ -788,9 +749,6 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 gceSTATUS
@@ -802,7 +760,6 @@ gckMCFE_Execute(
     IN gctUINT32 Bytes
     )
 {
-#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
     gctUINT32 regBase;
     gcsMCFE_DESCRIPTOR *desc;
     gcsMCFE_CHANNEL * channel  = &Hardware->mcFE->channels[ChannelId];
@@ -815,8 +772,8 @@ gckMCFE_Execute(
     while (_NextPtr(ringBuf->writePtr) == ringBuf->readPtr)
     {
         gctUINT32 data;
-        regBase = Priority ? GCREG_MCFE_PRI_DESC_FIFO_RD_PTR_Address
-                : GCREG_MCFE_STD_DESC_FIFO_RD_PTR_Address;
+        regBase = Priority ? 0x02B00
+                : 0x02700;
 
         gcmkVERIFY_OK(gckOS_ReadRegisterEx(Hardware->os,
                                            Hardware->core,
@@ -836,8 +793,8 @@ gckMCFE_Execute(
         }
     }
 
-    regBase = Priority ? GCREG_MCFE_PRI_DESC_FIFO_WR_PTR_Address
-            : GCREG_MCFE_STD_DESC_FIFO_WR_PTR_Address;
+    regBase = Priority ? 0x02A00
+            : 0x02600;
 
     /* ringBufLogical is in uint32, 2 uint32 contributes 1 descriptr. */
     desc = (gcsMCFE_DESCRIPTOR *)&ringBuf->ringBufLogical[ringBuf->writePtr * 2];
@@ -875,9 +832,6 @@ gckMCFE_Execute(
                                         ringBuf->writePtr));
 
     return gcvSTATUS_OK;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
 }
 
 
index 87f5f3578ce3a166a3390da7377cd7dcf0be8984..c57374a6691ffe6979db3806374002541d6ca370 100644 (file)
@@ -1670,12 +1670,13 @@ gckWLFE_AtomicExecute(
     )
 {
     gctUINT32 control;
+    gceSTATUS status = gcvSTATUS_OK;
 
     /* Enable all events. */
-    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U);
+    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
 
     /* Write address register. */
-    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address);
+    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address));
 
     /* Build control register. */
     control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1715,25 +1716,25 @@ gckWLFE_AtomicExecute(
     }
 
     /* Make sure writing to command buffer and previous AHB register is done. */
-    gckOS_MemoryBarrier(Hardware->os, gcvNULL);
+    gcmkONERROR(gckOS_MemoryBarrier(Hardware->os, gcvNULL));
 
     /* Write control register. */
     switch (Hardware->options.secureMode)
     {
     case gcvSECURE_NONE:
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
+        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
         break;
     case gcvSECURE_IN_NORMAL:
 
 #if defined(__KERNEL__)
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
+        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
 #endif
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control);
+        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control));
         break;
 #if gcdENABLE_TRUST_APPLICATION
     case gcvSECURE_IN_TA:
         /* Send message to TA. */
-        gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes);
+        gcmkONERROR(gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes));
         break;
 #endif
     default:
@@ -1748,6 +1749,10 @@ gckWLFE_AtomicExecute(
 
     /* Success. */
     return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    return status;
 }
 
 
index 6681a909a94dfab490ab527f3d157156eae4950f..2dcf09c5244122de97e79f6757b34065fe9d1580 100644 (file)
@@ -128,6 +128,7 @@ gctCONST_STRING _DispatchText[] =
     gcmDEFINE2TEXT(gcvHAL_SET_DEBUG_LEVEL_ZONE),
     gcmDEFINE2TEXT(gcvHAL_DEBUG_DUMP),
     gcmDEFINE2TEXT(gcvHAL_UPDATE_DEBUG_CALLBACK),
+    gcmDEFINE2TEXT(gcvHAL_CONFIG_CTX_FRAMEWORK),
     gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_STATE),
     gcmDEFINE2TEXT(gcvHAL_DUMP_EVENT),
     gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_PROFILE),
@@ -142,9 +143,11 @@ gctCONST_STRING _DispatchText[] =
     gcmDEFINE2TEXT(gcvHAL_WAIT_NATIVE_FENCE),
     gcmDEFINE2TEXT(gcvHAL_SHBUF),
     gcmDEFINE2TEXT(gcvHAL_GET_GRAPHIC_BUFFER_FD),
+    gcmDEFINE2TEXT(gcvHAL_SET_VIDEO_MEMORY_METADATA),
     gcmDEFINE2TEXT(gcvHAL_GET_VIDEO_MEMORY_FD),
     gcmDEFINE2TEXT(gcvHAL_DESTROY_MMU),
     gcmDEFINE2TEXT(gcvHAL_WAIT_FENCE),
+    gcmDEFINE2TEXT(gcvHAL_DEVICE_MUTEX),
     gcmDEFINE2TEXT(gcvHAL_DEC200_TEST),
     gcmDEFINE2TEXT(gcvHAL_DEC300_READ),
     gcmDEFINE2TEXT(gcvHAL_DEC300_WRITE),
@@ -476,6 +479,8 @@ gckKERNEL_Construct(
         kernel->timers[i].stopTime = 0;
     }
 
+    gcmkONERROR(gckOS_CreateMutex(Os, &kernel->vidMemBlockMutex));
+
     /* Save context. */
     kernel->context = Context;
 
@@ -500,6 +505,9 @@ gckKERNEL_Construct(
         _SetRecovery(kernel, recovery, stuckDump);
     }
 
+    status = gckOS_QueryOption(Os, "sRAMLoopMode", &data);
+    kernel->sRAMLoopMode = (status == gcvSTATUS_OK) ? data : 0;
+
     /* Need the kernel reference before gckKERNEL_Construct() completes.
        gckOS_MapPagesEx() is called to map kernel virtual command buffers. */
     *Kernel = kernel;
@@ -512,12 +520,14 @@ gckKERNEL_Construct(
         /* Set pointer to gckKERNEL object in gckHARDWARE object. */
         kernel->hardware->kernel = kernel;
 
-        kernel->sRAMNonExclusive = kernel->hardware->sRAMNonExclusive;
+        kernel->sRAMIndex = 0;
+        kernel->extSRAMIndex = 0;
 
-        for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_COUNT; i++)
+        for (i = gcvSRAM_INTERNAL0; i < gcvSRAM_INTER_COUNT; i++)
         {
-            kernel->sRAMVideoMem[i] = kernel->hardware->sRAMVideoMem[i];
-            kernel->sRAMPhysical[i] = kernel->hardware->sRAMPhysical[i];
+            kernel->sRAMVidMem[i]    = kernel->hardware->sRAMVidMem[i];
+            kernel->sRAMPhysical[i]  = kernel->hardware->sRAMPhysical[i];
+            kernel->sRAMPhysFaked[i] = gcvFALSE;
         }
 
         kernel->timeOut = kernel->hardware->type == gcvHARDWARE_2D
@@ -551,7 +561,7 @@ gckKERNEL_Construct(
         }
 
         gcmkONERROR(
-            gckMMU_SetupPerHardware(kernel->mmu, kernel->hardware, kernel->device));
+            gckMMU_SetupSRAM(kernel->mmu, kernel->hardware, kernel->device));
 
         if (kernel->hardware->mmuVersion && !kernel->mmu->dynamicAreaSetuped)
         {
@@ -561,14 +571,17 @@ gckKERNEL_Construct(
             kernel->mmu->dynamicAreaSetuped = gcvTRUE;
         }
 
-        /* Flush MTLB table. */
-        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
-            kernel,
-            kernel->mmu->mtlbVideoMem,
-            0,
-            kernel->mmu->mtlbLogical,
-            kernel->mmu->mtlbSize
-            ));
+        if (kernel->hardware->mmuVersion > 0)
+        {
+            /* Flush MTLB table. */
+            gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+                kernel,
+                kernel->mmu->mtlbVideoMem,
+                0,
+                kernel->mmu->mtlbLogical,
+                kernel->mmu->mtlbSize
+                ));
+        }
 #endif
 
         kernel->contiguousBaseAddress = kernel->mmu->contiguousBaseAddress;
@@ -780,6 +793,8 @@ gckKERNEL_Destroy(
         gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
     }
 
+    gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->vidMemBlockMutex));
+
     /* Destroy the database. */
     if (Kernel->dbCreated)
     {
@@ -930,9 +945,9 @@ gckKERNEL_AllocateVideoMemory(
     gctBOOL cacheable = gcvFALSE;
     gctBOOL secure = gcvFALSE;
     gctBOOL fastPools = gcvFALSE;
+    gctBOOL virtualPool4K = gcvFALSE;
     gctBOOL hasFastPools = gcvFALSE;
     gctSIZE_T bytes = *Bytes;
-    gctUINT32 sRAMIndex = 1;
 
     gcmkHEADER_ARG("Kernel=%p *Pool=%d *Bytes=%lu Alignment=%lu Type=%d",
                    Kernel, *Pool, *Bytes, Alignment, Type);
@@ -950,6 +965,12 @@ gckKERNEL_AllocateVideoMemory(
         Flag &= ~gcvALLOC_FLAG_FAST_POOLS;
     }
 
+    if (Flag & gcvALLOC_FLAG_4K_PAGES)
+    {
+        virtualPool4K = gcvTRUE;
+        Flag &= ~gcvALLOC_FLAG_4K_PAGES;
+    }
+
 #if gcdALLOC_ON_FAULT
     if (Type == gcvVIDMEM_COLOR_BUFFER)
     {
@@ -1028,6 +1049,25 @@ AllocateMemory:
                 status = gcvSTATUS_OUT_OF_MEMORY;
             }
             else
+#endif
+#if gcdENABLE_GPU_1M_PAGE
+            if (!virtualPool4K && Kernel->core != gcvCORE_VG && Kernel->hardware->mmuVersion)
+            {
+                /* Create a gckVIDMEM_NODE from contiguous memory. */
+                status = gckVIDMEM_NODE_AllocateVirtualChunk(
+                            Kernel,
+                            pool,
+                            Type,
+                            Flag | gcvALLOC_FLAG_CONTIGUOUS,
+                            &bytes,
+                            &nodeObject);
+
+                if (gcmIS_SUCCESS(status))
+                {
+                    /* Memory allocated. */
+                    break;
+                }
+            }
 #endif
             {
                 /* Create a gckVIDMEM_NODE from contiguous memory. */
@@ -1051,6 +1091,26 @@ AllocateMemory:
                 break;
             }
 
+#if gcdENABLE_GPU_1M_PAGE
+            /* Try non-contiguous virtual chunk. */
+            if (!virtualPool4K && Kernel->hardware->mmuVersion && Kernel->core != gcvCORE_VG)
+            {
+                /* Create a gckVIDMEM_NODE from contiguous memory. */
+                status = gckVIDMEM_NODE_AllocateVirtualChunk(
+                            Kernel,
+                            pool,
+                            Type,
+                            Flag | gcvALLOC_FLAG_NON_CONTIGUOUS,
+                            &bytes,
+                            &nodeObject);
+
+                if (gcmIS_SUCCESS(status))
+                {
+                    /* Memory allocated. */
+                    break;
+                }
+            }
+#endif
             /* Try non-contiguous virtual. */
             /* Create a gckVIDMEM_NODE for virtual memory. */
             gcmkONERROR(
@@ -1066,9 +1126,13 @@ AllocateMemory:
         /* gcvPOOL_SYSTEM/gcvPOOL_SRAM can't be cacheable. */
         else if (cacheable == gcvFALSE && secure == gcvFALSE)
         {
-            /* Get pointer to gckVIDMEM object for pool. */
-            Kernel->sRAMIndex = sRAMIndex;
+#ifdef EMULATOR
+            /* Cmodel only support 1 SRAM currently. */
+            Kernel->sRAMIndex = 0;
+            Kernel->extSRAMIndex = 0;
+#endif
 
+            /* Get pointer to gckVIDMEM object for pool. */
             status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
 
             if (gcmIS_SUCCESS(status))
@@ -1094,7 +1158,9 @@ AllocateMemory:
                                                            pool,
                                                            Type,
                                                            Alignment,
-                                                           (pool == gcvPOOL_SYSTEM || pool == gcvPOOL_SRAM),
+                                                           (pool == gcvPOOL_SYSTEM ||
+                                                            pool == gcvPOOL_INTERNAL_SRAM ||
+                                                            pool == gcvPOOL_EXTERNAL_SRAM),
                                                            &bytes,
                                                            &nodeObject);
                 }
@@ -1116,10 +1182,10 @@ AllocateMemory:
         else
         if (pool == gcvPOOL_LOCAL_EXTERNAL)
         {
-            if (Kernel->sRAMNonExclusive)
+            if (Kernel->sRAMLoopMode)
             {
-                /* Advance to SRAM memory. */
-                pool = gcvPOOL_SRAM;
+                /* Advance to Internal SRAM memory block. */
+                pool = gcvPOOL_INTERNAL_SRAM;
             }
             else
             {
@@ -1129,11 +1195,11 @@ AllocateMemory:
         }
 
         else
-        if (pool == gcvPOOL_SRAM)
+        if (pool == gcvPOOL_INTERNAL_SRAM)
         {
-            if (sRAMIndex < gcvSRAM_COUNT - 1)
+            if (Kernel->sRAMIndex < gcvSRAM_INTER_COUNT - 1 && !Kernel->sRAMPhysFaked[Kernel->sRAMIndex])
             {
-                sRAMIndex++;
+                Kernel->sRAMIndex++;
                 loopCount++;
             }
             else
@@ -1228,6 +1294,16 @@ _AllocateLinearMemory(
 
     gcmkVERIFY_ARGUMENT(bytes != 0);
 
+    if (Interface->u.AllocateLinearVideoMemory.sRAMIndex >= 0)
+    {
+        Kernel->sRAMIndex = Interface->u.AllocateLinearVideoMemory.sRAMIndex;
+    }
+
+    if (Interface->u.AllocateLinearVideoMemory.extSRAMIndex >= 0)
+    {
+        Kernel->extSRAMIndex = Interface->u.AllocateLinearVideoMemory.extSRAMIndex;
+    }
+
     /* Allocate video memory node. */
     gcmkONERROR(
         gckKERNEL_AllocateVideoMemory(Kernel,
@@ -1418,11 +1494,6 @@ _LockVideoMemory(
     Interface->u.LockVideoMemory.physicalAddress = physical;
     Interface->u.LockVideoMemory.gid = gid;
 
-#if gcdSECURE_USER
-    /* Return logical address as physical address. */
-    Interface->u.LockVideoMemory.address = (gctUINT32)(gctUINTPTR_T)logical;
-#endif
-
     gcmkONERROR(
         gckKERNEL_AddProcessDB(Kernel,
                                ProcessID,
@@ -1496,6 +1567,7 @@ _UnlockVideoMemory(
     gceSTATUS status;
     gckVIDMEM_NODE nodeObject;
     gcuVIDMEM_NODE_PTR node;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
     gctSIZE_T bytes;
 
     gcmkHEADER_ARG("Kernel=%p ProcessID=%d",
@@ -1526,8 +1598,21 @@ _UnlockVideoMemory(
     /* Leave deref handle and deref node in later operation. */
 
     node = nodeObject->node;
-    bytes = (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
-          ? node->VidMem.bytes : node->Virtual.bytes;
+
+    vidMemBlock = node->VirtualChunk.parent;
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        bytes = node->VidMem.bytes;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        bytes = node->VirtualChunk.bytes;
+    }
+    else
+    {
+        bytes = node->Virtual.bytes;
+    }
 
     Interface->u.UnlockVideoMemory.pool  = nodeObject->pool;
     Interface->u.UnlockVideoMemory.bytes = bytes;
@@ -1757,6 +1842,111 @@ OnError:
     return status;
 }
 
+/*******************************************************************************
+**
+**  gckKERNEL_SetVidMemMetadata
+**
+**  Set/Get metadata to/from gckVIDMEM_NODE object.
+**
+**  INPUT:
+**
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**      gctUINT32 ProcessID
+**          ProcessID of current process.
+**
+**  INOUT:
+**
+**      gcsHAL_INTERFACE * Interface
+**          Pointer to a interface structure
+*/
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include <linux/dma-buf.h>
+
+gceSTATUS
+_SetVidMemMetadata(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    INOUT gcsHAL_INTERFACE * Interface
+    )
+{
+    gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+    gckVIDMEM_NODE nodeObj = gcvNULL;
+
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d", Kernel, ProcessID);
+
+    gcmkONERROR(gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Interface->u.SetVidMemMetadata.node, &nodeObj));
+
+    if (Interface->u.SetVidMemMetadata.readback)
+    {
+        Interface->u.SetVidMemMetadata.ts_fd            = nodeObj->metadata.ts_fd;
+        Interface->u.SetVidMemMetadata.fc_enabled       = nodeObj->metadata.fc_enabled;
+        Interface->u.SetVidMemMetadata.fc_value         = nodeObj->metadata.fc_value;
+        Interface->u.SetVidMemMetadata.fc_value_upper   = nodeObj->metadata.fc_value_upper;
+        Interface->u.SetVidMemMetadata.compressed       = nodeObj->metadata.compressed;
+        Interface->u.SetVidMemMetadata.compress_format  = nodeObj->metadata.compress_format;
+    }
+    else
+    {
+#ifdef gcdANDROID
+        if (nodeObj->metadata.ts_address == 0 && nodeObj->tsNode != NULL)
+        {
+            gctUINT32 PhysicalAddress = 0;
+
+            /* Lock for GPU address. */
+            gcmkONERROR(gckVIDMEM_NODE_Lock(Kernel, nodeObj->tsNode, &PhysicalAddress));
+
+            nodeObj->metadata.ts_address = (
+                    PhysicalAddress + Kernel->hardware->baseAddress);
+
+            gcmkONERROR(gckVIDMEM_NODE_Unlock(Kernel, nodeObj->tsNode, ProcessID, gcvNULL));
+        }
+#else
+        nodeObj->metadata.ts_fd             = Interface->u.SetVidMemMetadata.ts_fd;
+
+        if (nodeObj->metadata.ts_fd >= 0)
+        {
+            nodeObj->metadata.ts_dma_buf    = dma_buf_get(nodeObj->metadata.ts_fd);
+
+            if (IS_ERR(nodeObj->metadata.ts_dma_buf))
+            {
+                gcmkONERROR(gcvSTATUS_NOT_FOUND);
+            }
+
+            dma_buf_put(nodeObj->metadata.ts_dma_buf);
+        }
+        else
+        {
+            nodeObj->metadata.ts_dma_buf    = NULL;
+        }
+#endif
+
+        nodeObj->metadata.fc_enabled        = Interface->u.SetVidMemMetadata.fc_enabled;
+        nodeObj->metadata.fc_value          = Interface->u.SetVidMemMetadata.fc_value;
+        nodeObj->metadata.fc_value_upper    = Interface->u.SetVidMemMetadata.fc_value_upper;
+        nodeObj->metadata.compressed        = Interface->u.SetVidMemMetadata.compressed;
+        nodeObj->metadata.compress_format   = Interface->u.SetVidMemMetadata.compress_format;
+    }
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+#else
+
+gceSTATUS
+_SetVidMemMetadata(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    INOUT gcsHAL_INTERFACE * Interface
+    )
+{
+    gcmkFATAL("The kernel did NOT support CONFIG_DMA_SHARED_BUFFER");
+    return gcvSTATUS_NOT_SUPPORTED;
+}
+#endif
 
 static gceSTATUS
 _GetVideoMemoryFd(
@@ -1861,12 +2051,12 @@ gckKERNEL_ConfigPowerManagement(
 
     gcmkHEADER();
 
-    gcmkONERROR(gckHARDWARE_SetPowerManagement(Kernel->hardware, enable));
+    gcmkONERROR(gckHARDWARE_EnablePowerManagement(Kernel->hardware, enable));
 
     if (enable == gcvFALSE)
     {
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Kernel->hardware, gcvPOWER_ON));
+            gckHARDWARE_SetPowerState(Kernel->hardware, gcvPOWER_ON));
     }
 
     gcmkFOOTER_NO();
@@ -1891,6 +2081,8 @@ gckKERNEL_CacheOperation(
     gceSTATUS status;
     gckVIDMEM_NODE nodeObject = gcvNULL;
     gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
+    gctSIZE_T offset = 0;
     void *memHandle;
 
     gcmkHEADER_ARG("Kernel=%p pid=%u Node=%u op=%d Logical=%p Bytes=0x%lx",
@@ -1903,6 +2095,8 @@ gckKERNEL_CacheOperation(
 
     node = nodeObject->node;
 
+    vidMemBlock = node->VirtualChunk.parent;
+
     if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
         static gctBOOL printed;
@@ -1916,6 +2110,11 @@ gckKERNEL_CacheOperation(
         gcmkFOOTER_NO();
         return gcvSTATUS_OK;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        memHandle = vidMemBlock->physical;
+        offset = node->VirtualChunk.offset;
+    }
     else
     {
         memHandle = node->Virtual.physical;
@@ -1928,7 +2127,7 @@ gckKERNEL_CacheOperation(
         status = gckOS_CacheFlush(Kernel->os,
                                   ProcessID,
                                   memHandle,
-                                  0,
+                                  offset,
                                   Logical,
                                   Bytes);
         break;
@@ -1937,7 +2136,7 @@ gckKERNEL_CacheOperation(
         status = gckOS_CacheClean(Kernel->os,
                                   ProcessID,
                                   memHandle,
-                                  0,
+                                  offset,
                                   Logical,
                                   Bytes);
         break;
@@ -1946,7 +2145,7 @@ gckKERNEL_CacheOperation(
         status = gckOS_CacheInvalidate(Kernel->os,
                                        ProcessID,
                                        memHandle,
-                                       0,
+                                       offset,
                                        Logical,
                                        Bytes);
         break;
@@ -2137,7 +2336,8 @@ _Commit(
                                        subCommit,
                                        ProcessId,
                                        Commit->shared,
-                                       &Commit->commitStamp);
+                                       &Commit->commitStamp,
+                                       &Commit->contextSwitched);
 
             if (status != gcvSTATUS_INTERRUPTED)
             {
@@ -2430,10 +2630,6 @@ gckKERNEL_Dispatch(
 #endif
     gckKERNEL kernel = Kernel;
     gctUINT32 processID;
-#if gcdSECURE_USER
-    gcskSECURE_CACHE_PTR cache;
-    gctPOINTER logical;
-#endif
 #if !USE_NEW_LINUX_SIGNAL
     gctSIGNAL   signal;
 #endif
@@ -2462,10 +2658,6 @@ gckKERNEL_Dispatch(
     /* Get the current process ID. */
     gcmkONERROR(gckOS_GetProcessID(&processID));
 
-#if gcdSECURE_USER
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
-#endif
-
     /* Dispatch on command. */
     switch (Interface->command)
     {
@@ -2579,14 +2771,6 @@ gckKERNEL_Dispatch(
                                      gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
                                      (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes));
 
-#if gcdSECURE_USER
-        gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
-            Kernel,
-            cache,
-            gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
-            (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes));
-#endif
-
         gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physName);
         break;
 
@@ -2620,12 +2804,15 @@ gckKERNEL_Dispatch(
         break;
 
     case gcvHAL_EVENT_COMMIT:
-        gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
-            Kernel->device->commitMutex,
-            gcvINFINITE
-            ));
+        if (!Interface->commitMutex)
+        {
+            gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
+                Kernel->device->commitMutex,
+                gcvINFINITE
+                ));
 
-        commitMutexAcquired = gcvTRUE;
+            commitMutexAcquired = gcvTRUE;
+        }
         /* Commit an event queue. */
         if (Interface->engine == gcvENGINE_BLT)
         {
@@ -2643,17 +2830,22 @@ gckKERNEL_Dispatch(
                 Kernel->eventObj, gcmUINT64_TO_PTR(Interface->u.Event.queue), gcvFALSE));
         }
 
-        gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
-        commitMutexAcquired = gcvFALSE;
+        if (!Interface->commitMutex)
+        {
+            gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
+            commitMutexAcquired = gcvFALSE;
+        }
         break;
 
     case gcvHAL_COMMIT:
-        gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
-            Device->commitMutex,
-            gcvINFINITE
-            ));
-
-        commitMutexAcquired = gcvTRUE;
+        if (!Interface->commitMutex)
+        {
+            gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
+                Device->commitMutex,
+                gcvINFINITE
+                ));
+            commitMutexAcquired = gcvTRUE;
+        }
 
         gcmkONERROR(_Commit(Device,
                             Kernel->hardware->type,
@@ -2661,8 +2853,11 @@ gckKERNEL_Dispatch(
                             processID,
                             &Interface->u.Commit));
 
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Device->commitMutex));
-        commitMutexAcquired = gcvFALSE;
+        if (!Interface->commitMutex)
+        {
+            gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Device->commitMutex));
+            commitMutexAcquired = gcvFALSE;
+        }
         break;
 
 #if !USE_NEW_LINUX_SIGNAL
@@ -2749,9 +2944,8 @@ gckKERNEL_Dispatch(
     case gcvHAL_SET_POWER_MANAGEMENT_STATE:
         /* Set the power management state. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(
-                Kernel->hardware,
-                Interface->u.SetPowerManagement.state));
+            gckHARDWARE_SetPowerState(Kernel->hardware,
+                                      Interface->u.SetPowerManagement.state));
         break;
 
     case gcvHAL_QUERY_POWER_MANAGEMENT_STATE:
@@ -2759,7 +2953,7 @@ gckKERNEL_Dispatch(
         Interface->u.QueryPowerManagement.isIdle = gcvFALSE;
 
         /* Query the power management state. */
-        gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+        gcmkONERROR(gckHARDWARE_QueryPowerState(
             Kernel->hardware,
             &Interface->u.QueryPowerManagement.state));
 
@@ -2776,7 +2970,7 @@ gckKERNEL_Dispatch(
 
             gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
             powerMutexAcquired = gcvTRUE;
-            gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+            gcmkONERROR(gckHARDWARE_QueryPowerState(Kernel->hardware,
                                                               &power));
             if (power == gcvPOWER_ON)
             {
@@ -2810,7 +3004,7 @@ gckKERNEL_Dispatch(
 
             gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
             powerMutexAcquired = gcvTRUE;
-            gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+            gcmkONERROR(gckHARDWARE_QueryPowerState(Kernel->hardware,
                                                                   &power));
             if (power == gcvPOWER_ON)
             {
@@ -2922,7 +3116,7 @@ gckKERNEL_Dispatch(
 
             _DumpDriverConfigure(Kernel);
 
-            gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+            gcmkONERROR(gckHARDWARE_QueryPowerState(
                 Kernel->hardware,
                 &power
                 ));
@@ -3122,6 +3316,10 @@ gckKERNEL_Dispatch(
         gcmkONERROR(_ImportVideoMemory(Kernel, processID, Interface));
         break;
 
+    case gcvHAL_SET_VIDEO_MEMORY_METADATA:
+        gcmkONERROR(_SetVidMemMetadata(Kernel, processID, Interface));
+        break;
+
     case gcvHAL_GET_VIDEO_MEMORY_FD:
         gcmkONERROR(_GetVideoMemoryFd(Kernel, processID, Interface));
         break;
@@ -3278,6 +3476,20 @@ gckKERNEL_Dispatch(
         gcmkONERROR(_WaitFence(Kernel, processID, Interface));
         break;
 
+    case gcvHAL_DEVICE_MUTEX:
+        if (Interface->u.DeviceMutex.isMutexLocked)
+        {
+            gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
+                Kernel->device->commitMutex,
+                gcvINFINITE
+                ));
+        }
+        else
+        {
+            gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
+        }
+        break;
+
 #if gcdDEC_ENABLE_AHB
     case gcvHAL_DEC300_READ:
         gcmkONERROR(viv_dec300_read(
@@ -3508,509 +3720,6 @@ OnError:
     return status;
 }
 
-#if gcdSECURE_USER
-gceSTATUS
-gckKERNEL_MapLogicalToPhysical(
-    IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN OUT gctPOINTER * Data
-    )
-{
-    gceSTATUS status;
-    static gctBOOL baseAddressValid = gcvFALSE;
-    static gctUINT32 baseAddress;
-    gctBOOL needBase;
-    gcskLOGICAL_CACHE_PTR slot;
-
-    gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x *Data=0x%x",
-                   Kernel, Cache, gcmOPT_POINTER(Data));
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-
-    if (!baseAddressValid)
-    {
-        /* Get base address. */
-        gcmkONERROR(gckHARDWARE_GetBaseAddress(Kernel->hardware, &baseAddress));
-
-        baseAddressValid = gcvTRUE;
-    }
-
-    /* Does this state load need a base address? */
-    gcmkONERROR(gckHARDWARE_NeedBaseAddress(Kernel->hardware,
-                                            ((gctUINT32_PTR) Data)[-1],
-                                            &needBase));
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
-    {
-        gcskLOGICAL_CACHE_PTR next;
-        gctINT i;
-
-        /* Walk all used cache slots. */
-        for (i = 1, slot = Cache->cache[0].next, next = gcvNULL;
-             (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-             ++i, slot = slot->next
-        )
-        {
-            if (slot->logical == *Data)
-            {
-                /* Bail out. */
-                next = slot;
-                break;
-            }
-        }
-
-        /* See if we had a miss. */
-        if (next == gcvNULL)
-        {
-            /* Use the tail of the cache. */
-            slot = Cache->cache[0].prev;
-
-            /* Initialize the cache line. */
-            slot->logical = *Data;
-
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
-
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
-        }
-
-        /* Move slot to head of list. */
-        if (slot != Cache->cache[0].next)
-        {
-            /* Unlink. */
-            slot->prev->next = slot->next;
-            slot->next->prev = slot->prev;
-
-            /* Move to head of chain. */
-            slot->prev       = &Cache->cache[0];
-            slot->next       = Cache->cache[0].next;
-            slot->prev->next = slot;
-            slot->next->prev = slot;
-        }
-    }
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
-    {
-        gctINT i;
-        gcskLOGICAL_CACHE_PTR next = gcvNULL;
-        gcskLOGICAL_CACHE_PTR oldestSlot = gcvNULL;
-        slot = gcvNULL;
-
-        if (Cache->cacheIndex != gcvNULL)
-        {
-            /* Walk the cache forwards. */
-            for (i = 1, slot = Cache->cacheIndex;
-                 (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-                 ++i, slot = slot->next)
-            {
-                if (slot->logical == *Data)
-                {
-                    /* Bail out. */
-                    next = slot;
-                    break;
-                }
-
-                /* Determine age of this slot. */
-                if ((oldestSlot       == gcvNULL)
-                ||  (oldestSlot->stamp > slot->stamp)
-                )
-                {
-                    oldestSlot = slot;
-                }
-            }
-
-            if (next == gcvNULL)
-            {
-                /* Walk the cache backwards. */
-                for (slot = Cache->cacheIndex->prev;
-                     (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-                     ++i, slot = slot->prev)
-                {
-                    if (slot->logical == *Data)
-                    {
-                        /* Bail out. */
-                        next = slot;
-                        break;
-                    }
-
-                    /* Determine age of this slot. */
-                    if ((oldestSlot       == gcvNULL)
-                    ||  (oldestSlot->stamp > slot->stamp)
-                    )
-                    {
-                        oldestSlot = slot;
-                    }
-                }
-            }
-        }
-
-        /* See if we had a miss. */
-        if (next == gcvNULL)
-        {
-            if (Cache->cacheFree != 0)
-            {
-                slot = &Cache->cache[Cache->cacheFree];
-                gcmkASSERT(slot->logical == gcvNULL);
-
-                ++ Cache->cacheFree;
-                if (Cache->cacheFree >= gcmCOUNTOF(Cache->cache))
-                {
-                    Cache->cacheFree = 0;
-                }
-            }
-            else
-            {
-                /* Use the oldest cache slot. */
-                gcmkASSERT(oldestSlot != gcvNULL);
-                slot = oldestSlot;
-
-                /* Unlink from the chain. */
-                slot->prev->next = slot->next;
-                slot->next->prev = slot->prev;
-
-                /* Append to the end. */
-                slot->prev       = Cache->cache[0].prev;
-                slot->next       = &Cache->cache[0];
-                slot->prev->next = slot;
-                slot->next->prev = slot;
-            }
-
-            /* Initialize the cache line. */
-            slot->logical = *Data;
-
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
-
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
-        }
-
-        /* Save time stamp. */
-        slot->stamp = ++ Cache->cacheStamp;
-
-        /* Save current slot for next lookup. */
-        Cache->cacheIndex = slot;
-    }
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-    {
-        gctINT i;
-        gctUINT32 data = gcmPTR2INT32(*Data);
-        gctUINT32 key, index;
-        gcskLOGICAL_CACHE_PTR hash;
-
-        /* Generate a hash key. */
-        key   = (data >> 24) + (data >> 16) + (data >> 8) + data;
-        index = key % gcmCOUNTOF(Cache->hash);
-
-        /* Get the hash entry. */
-        hash = &Cache->hash[index];
-
-        for (slot = hash->nextHash, i = 0;
-             (slot != gcvNULL) && (i < gcdSECURE_CACHE_SLOTS);
-             slot = slot->nextHash, ++i
-        )
-        {
-            if (slot->logical == (*Data))
-            {
-                break;
-            }
-        }
-
-        if (slot == gcvNULL)
-        {
-            /* Grab from the tail of the cache. */
-            slot = Cache->cache[0].prev;
-
-            /* Unlink slot from any hash table it is part of. */
-            if (slot->prevHash != gcvNULL)
-            {
-                slot->prevHash->nextHash = slot->nextHash;
-            }
-            if (slot->nextHash != gcvNULL)
-            {
-                slot->nextHash->prevHash = slot->prevHash;
-            }
-
-            /* Initialize the cache line. */
-            slot->logical = *Data;
-
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
-
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
-
-            if (hash->nextHash != gcvNULL)
-            {
-                gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
-                               "Hash Collision: logical=0x%x key=0x%08x",
-                               *Data, key);
-            }
-
-            /* Insert the slot at the head of the hash list. */
-            slot->nextHash     = hash->nextHash;
-            if (slot->nextHash != gcvNULL)
-            {
-                slot->nextHash->prevHash = slot;
-            }
-            slot->prevHash     = hash;
-            hash->nextHash     = slot;
-        }
-
-        /* Move slot to head of list. */
-        if (slot != Cache->cache[0].next)
-        {
-            /* Unlink. */
-            slot->prev->next = slot->next;
-            slot->next->prev = slot->prev;
-
-            /* Move to head of chain. */
-            slot->prev       = &Cache->cache[0];
-            slot->next       = Cache->cache[0].next;
-            slot->prev->next = slot;
-            slot->next->prev = slot;
-        }
-    }
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
-    {
-        gctUINT32 index = (gcmPTR2INT32(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
-
-        /* Get cache slot. */
-        slot = &Cache->cache[index];
-
-        /* Check for cache miss. */
-        if (slot->logical != *Data)
-        {
-            /* Initialize the cache line. */
-            slot->logical = *Data;
-
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
-
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
-        }
-    }
-#endif
-
-    /* Return DMA address. */
-    *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Data=0x%08x", *Data);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckKERNEL_FlushTranslationCache(
-    IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gctINT i;
-    gcskLOGICAL_CACHE_PTR slot;
-    gctUINT8_PTR ptr;
-
-    gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
-                   Kernel, Cache, Logical, Bytes);
-
-    /* Do we need to flush the entire cache? */
-    if (Logical == gcvNULL)
-    {
-        /* Clear all cache slots. */
-        for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
-        {
-            Cache->cache[i].logical  = gcvNULL;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-            Cache->cache[i].nextHash = gcvNULL;
-            Cache->cache[i].prevHash = gcvNULL;
-#endif
-}
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-        /* Zero the hash table. */
-        for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
-        {
-            Cache->hash[i].nextHash = gcvNULL;
-        }
-#endif
-
-        /* Reset the cache functionality. */
-        Cache->cacheIndex = gcvNULL;
-        Cache->cacheFree  = 1;
-        Cache->cacheStamp = 0;
-    }
-
-    else
-    {
-        gctUINT8_PTR low  = (gctUINT8_PTR) Logical;
-        gctUINT8_PTR high = low + Bytes;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
-        gcskLOGICAL_CACHE_PTR next;
-
-        /* Walk all used cache slots. */
-        for (i = 1, slot = Cache->cache[0].next;
-             (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-             ++i, slot = next
-        )
-        {
-            /* Save pointer to next slot. */
-            next = slot->next;
-
-            /* Test if this slot falls within the range to flush. */
-            ptr = (gctUINT8_PTR) slot->logical;
-            if ((ptr >= low) && (ptr < high))
-            {
-                /* Unlink slot. */
-                slot->prev->next = slot->next;
-                slot->next->prev = slot->prev;
-
-                /* Append slot to tail of cache. */
-                slot->prev       = Cache->cache[0].prev;
-                slot->next       = &Cache->cache[0];
-                slot->prev->next = slot;
-                slot->next->prev = slot;
-
-                /* Mark slot as empty. */
-                slot->logical = gcvNULL;
-            }
-        }
-
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
-        gcskLOGICAL_CACHE_PTR next;
-
-        for (i = 1, slot = Cache->cache[0].next;
-             (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-             ++i, slot = next)
-        {
-            /* Save pointer to next slot. */
-            next = slot->next;
-
-            /* Test if this slot falls within the range to flush. */
-            ptr = (gctUINT8_PTR) slot->logical;
-            if ((ptr >= low) && (ptr < high))
-            {
-                /* Test if this slot is the current slot. */
-                if (slot == Cache->cacheIndex)
-                {
-                    /* Move to next or previous slot. */
-                    Cache->cacheIndex = (slot->next->logical != gcvNULL)
-                                      ? slot->next
-                                      : (slot->prev->logical != gcvNULL)
-                                      ? slot->prev
-                                      : gcvNULL;
-                }
-
-                /* Unlink slot from cache. */
-                slot->prev->next = slot->next;
-                slot->next->prev = slot->prev;
-
-                /* Insert slot to head of cache. */
-                slot->prev       = &Cache->cache[0];
-                slot->next       = Cache->cache[0].next;
-                slot->prev->next = slot;
-                slot->next->prev = slot;
-
-                /* Mark slot as empty. */
-                slot->logical = gcvNULL;
-                slot->stamp   = 0;
-            }
-        }
-
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-        gctINT j;
-        gcskLOGICAL_CACHE_PTR hash, next;
-
-        /* Walk all hash tables. */
-        for (i = 0, hash = Cache->hash;
-             i < gcmCOUNTOF(Cache->hash);
-             ++i, ++hash)
-        {
-            /* Walk all slots in the hash. */
-            for (j = 0, slot = hash->nextHash;
-                 (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
-                 ++j, slot = next)
-            {
-                /* Save pointer to next slot. */
-                next = slot->next;
-
-                /* Test if this slot falls within the range to flush. */
-                ptr = (gctUINT8_PTR) slot->logical;
-                if ((ptr >= low) && (ptr < high))
-                {
-                    /* Unlink slot from hash table. */
-                    if (slot->prevHash == hash)
-                    {
-                        hash->nextHash = slot->nextHash;
-                    }
-                    else
-                    {
-                        slot->prevHash->nextHash = slot->nextHash;
-                    }
-
-                    if (slot->nextHash != gcvNULL)
-                    {
-                        slot->nextHash->prevHash = slot->prevHash;
-                    }
-
-                    /* Unlink slot from cache. */
-                    slot->prev->next = slot->next;
-                    slot->next->prev = slot->prev;
-
-                    /* Append slot to tail of cache. */
-                    slot->prev       = Cache->cache[0].prev;
-                    slot->next       = &Cache->cache[0];
-                    slot->prev->next = slot;
-                    slot->next->prev = slot;
-
-                    /* Mark slot as empty. */
-                    slot->logical  = gcvNULL;
-                    slot->prevHash = gcvNULL;
-                    slot->nextHash = gcvNULL;
-                }
-            }
-        }
-
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
-        gctUINT32 index;
-
-        /* Loop while inside the range. */
-        for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
-        {
-            /* Get index into cache for this range. */
-            index = (gcmPTR2INT32(low) % gcdSECURE_CACHE_SLOTS) + 1;
-            slot  = &Cache->cache[index];
-
-            /* Test if this slot falls within the range to flush. */
-            ptr = (gctUINT8_PTR) slot->logical;
-            if ((ptr >= low) && (ptr < high))
-            {
-                /* Remove entry from cache. */
-                slot->logical = gcvNULL;
-            }
-
-            /* Next block. */
-            low += gcdSECURE_CACHE_SLOTS;
-        }
-#endif
-    }
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-#endif
-
 /*******************************************************************************
 **
 **  gckKERNEL_Recovery
@@ -4034,10 +3743,6 @@ gckKERNEL_Recovery(
     gceSTATUS status;
     gckEVENT eventObj;
     gckHARDWARE hardware;
-#if gcdSECURE_USER
-    gctUINT32 processID;
-    gcskSECURE_CACHE_PTR cache;
-#endif
     gctUINT32 mask = 0;
     gctUINT32 i = 0, count = 0;
 #if gcdINTERRUPT_STATISTIC
@@ -4057,13 +3762,6 @@ gckKERNEL_Recovery(
     hardware = Kernel->hardware;
     gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
 
-#if gcdSECURE_USER
-    /* Flush the secure mapping cache. */
-    gcmkONERROR(gckOS_GetProcessID(&processID));
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
-    gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
-#endif
-
     if (Kernel->stuckDump == gcvSTUCK_DUMP_NONE)
     {
         gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
@@ -4521,6 +4219,7 @@ gckKERNEL_AllocateIntegerId(
     gctUINT32 pos;
     gctUINT32 n, i;
     gckOS os = database->os;
+    gctPOINTER * table = gcvNULL;
 
     gcmkHEADER_ARG("Database=%p Pointer=%p", Database, Pointer);
 
@@ -4528,7 +4227,6 @@ gckKERNEL_AllocateIntegerId(
 
     if (database->freeCount < 1)
     {
-        gctPOINTER * table = gcvNULL;
         gctUINT32 * bitmap = gcvNULL;
         gctUINT32 expand;
         gctUINT32 capacity;
@@ -4602,6 +4300,11 @@ gckKERNEL_AllocateIntegerId(
     return gcvSTATUS_OK;
 
 OnError:
+    if (table)
+    {
+        gckOS_Free(os, table);
+    }
+
     gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
 
     gcmkFOOTER();
@@ -5402,20 +5105,29 @@ gckDEVICE_Construct(
     {
         device->coreInfoArray[i].type = gcvHARDWARE_INVALID;
 
-        /* Initialize device SRAM. */
-        for (j = 0; j < gcvSRAM_COUNT; j++)
+        /* Initialize internal SRAM. */
+        for (j = 0; j < gcvSRAM_INTER_COUNT; j++)
         {
             device->sRAMBases[i][j] = gcvINVALID_PHYSICAL_ADDRESS;
             device->sRAMSizes[i][j] = 0;
+            device->sRAMPhysFaked[i][j] = gcvFALSE;
         }
     }
 
+    /* Initialize external SRAM. */
+    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+    {
+        device->extSRAMBases[i] = gcvINVALID_PHYSICAL_ADDRESS;
+        device->extSRAMSizes[i] = 0;
+    }
+
     device->defaultHwType = gcvHARDWARE_INVALID;
 
     gcmkONERROR(gckOS_CreateMutex(Os, &device->stuckDumpMutex));
     gcmkONERROR(gckOS_CreateMutex(Os, &device->commitMutex));
 
     device->os = Os;
+    device->showSRAMMapInfo = 0;
 
     *Device = device;
 
@@ -5801,17 +5513,16 @@ gckKERNEL_MapInTrustApplicaiton(
     return gcvSTATUS_OK;
 
 OnError:
-    if(physicalArrayLogical != gcvNULL)
+    if (physicalArrayLogical != gcvNULL)
+    {
         gcmkVERIFY_OK(gckOS_Free(
             Kernel->os,
             (gctPOINTER)physicalArrayLogical
             ));
+    }
+
     gcmkFOOTER();
     return status;
 }
 #endif
 
-/*******************************************************************************
-***** Test Code ****************************************************************
-*******************************************************************************/
-
index 8200f942dd1a64cbd7825d08fe2f1dc3cc3fa5f6..41f5947ca7e42ad89f6dd319f744e0d883d4cf77 100644 (file)
@@ -60,8 +60,8 @@
 #include "gc_hal_kernel_hardware.h"
 #include "gc_hal_kernel_hardware_fe.h"
 #include "gc_hal_driver.h"
-
 #include "gc_hal_kernel_mutex.h"
+#include "gc_hal_metadata.h"
 
 
 #if gcdSECURITY || gcdENABLE_TRUST_APPLICATION
@@ -193,6 +193,10 @@ extern "C" {
 #define gcdMMU_STLB_WRITEABLE       0x00000004
 
 #endif
+
+#define gcd1M_PAGE_SIZE (1 << 20)
+#define gcd1M_PAGE_SHIFT 20
+
 /*******************************************************************************
 ***** Stuck Dump Level ********************************************************/
 
@@ -213,67 +217,11 @@ extern "C" {
 #define gcvSTUCK_DUMP_ALL_COMMAND   4
 
 /*******************************************************************************
-***** Process Secure Cache ****************************************************/
-
-#define gcdSECURE_CACHE_LRU         1
-#define gcdSECURE_CACHE_LINEAR      2
-#define gcdSECURE_CACHE_HASH        3
-#define gcdSECURE_CACHE_TABLE       4
+***** Page table **************************************************************/
 
 #define gcvPAGE_TABLE_DIRTY_BIT_OTHER   (1 << 0)
 #define gcvPAGE_TABLE_DIRTY_BIT_FE      (1 << 1)
 
-
-typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR;
-typedef struct _gcskLOGICAL_CACHE   gcskLOGICAL_CACHE;
-struct _gcskLOGICAL_CACHE
-{
-    /* Logical address. */
-    gctPOINTER                      logical;
-
-    /* DMAable address. */
-    gctUINT32                       dma;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-    /* Pointer to the previous and next hash tables. */
-    gcskLOGICAL_CACHE_PTR           nextHash;
-    gcskLOGICAL_CACHE_PTR           prevHash;
-#endif
-
-#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
-    /* Pointer to the previous and next slot. */
-    gcskLOGICAL_CACHE_PTR           next;
-    gcskLOGICAL_CACHE_PTR           prev;
-#endif
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
-    /* Time stamp. */
-    gctUINT64                       stamp;
-#endif
-};
-
-typedef struct _gcskSECURE_CACHE * gcskSECURE_CACHE_PTR;
-typedef struct _gcskSECURE_CACHE
-{
-    /* Cache memory. */
-    gcskLOGICAL_CACHE               cache[1 + gcdSECURE_CACHE_SLOTS];
-
-    /* Last known index for LINEAR mode. */
-    gcskLOGICAL_CACHE_PTR           cacheIndex;
-
-    /* Current free slot for LINEAR mode. */
-    gctUINT32                       cacheFree;
-
-    /* Time stamp for LINEAR mode. */
-    gctUINT64                       cacheStamp;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-    /* Hash table for HASH mode. */
-    gcskLOGICAL_CACHE              hash[256];
-#endif
-}
-gcskSECURE_CACHE;
-
 /*******************************************************************************
 ***** Process Database Management *********************************************/
 
@@ -351,11 +299,6 @@ typedef struct _gcsDATABASE
     /* Pointer to database. */
     gcsDATABASE_RECORD_PTR              list[48];
 
-#if gcdSECURE_USER
-    /* Secure cache. */
-    gcskSECURE_CACHE                    cache;
-#endif
-
     gctPOINTER                          handleDatabase;
     gctPOINTER                          handleDatabaseMutex;
 }
@@ -458,19 +401,13 @@ gckKERNEL_FindHandleDatbase(
 gceSTATUS
 gckMMU_GetPageEntry(
     IN gckMMU Mmu,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctUINT32_PTR *PageTable
     );
 
 gceSTATUS
-gckMMU_FreePagesEx(
-    IN gckMMU Mmu,
-    IN gctUINT32 Address,
-    IN gctSIZE_T PageCount
-    );
-
-gceSTATUS
-gckMMU_SetupPerHardware(
+gckMMU_SetupSRAM(
     IN gckMMU Mmu,
     IN gckHARDWARE Hardware,
     IN gckDEVICE Device
@@ -538,16 +475,6 @@ gckKERNEL_DeleteName(
     IN gctUINT32 Name
     );
 
-#if gcdSECURE_USER
-/* Get secure cache from the process database. */
-gceSTATUS
-gckKERNEL_GetProcessDBCache(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    OUT gcskSECURE_CACHE_PTR * Cache
-    );
-#endif
-
 /*******************************************************************************
 ********* Timer Management ****************************************************/
 typedef struct _gcsTIMER *           gcsTIMER_PTR;
@@ -678,18 +605,25 @@ struct _gckKERNEL
     gctUINT32                   restoreAddress;
     gctINT32                    restoreMask;
 
+    gckVIDMEM_BLOCK             vidMemBlock;
+    gctPOINTER                  vidMemBlockMutex;
+
     gctUINT32                   contiguousBaseAddress;
     gctUINT32                   externalBaseAddress;
     gctUINT32                   internalBaseAddress;
 
+    /* External shared SRAM. */
+    gctUINT32                   extSRAMBaseAddresses[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMIndex;
+
     /* Per core SRAM description. */
     gctUINT32                   sRAMIndex;
-    gckVIDMEM                   sRAMVideoMem[gcvSRAM_COUNT];
-    gctPHYS_ADDR                sRAMPhysical[gcvSRAM_COUNT];
-    gctUINT32                   sRAMBaseAddresses[gcvSRAM_COUNT];
-    gctUINT32                   sRAMSizes[gcvSRAM_COUNT];
-    /* SRAM mode. */
-    gctUINT32                   sRAMNonExclusive;
+    gckVIDMEM                   sRAMVidMem[gcvSRAM_INTER_COUNT];
+    gctPHYS_ADDR                sRAMPhysical[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMBaseAddresses[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMSizes[gcvSRAM_INTER_COUNT];
+    gctBOOL                     sRAMPhysFaked[gcvSRAM_INTER_COUNT];
+    gctUINT64                   sRAMLoopMode;
 };
 
 struct _FrequencyHistory
@@ -902,13 +836,6 @@ struct _gckCOMMAND
     /* Kernel process ID. */
     gctUINT32                   kernelProcessID;
 
-#if gcdSECURE_USER
-    /* Hint array copy buffer. */
-    gctBOOL                     hintArrayAllocated;
-    gctUINT                     hintArraySize;
-    gctUINT32_PTR               hintArray;
-#endif
-
 #if gcdRECORD_COMMAND
     gckRECORDER                 recorder;
 #endif
@@ -1215,6 +1142,9 @@ typedef union _gcuVIDMEM_NODE
         /* Locked counter. */
         gctINT32                lockeds[gcvHARDWARE_NUM_TYPES];
 
+        /* MMU page size type */
+        gcePAGE_TYPE            pageType;
+
         gceVIDMEM_TYPE          type;
 
         /* Secure GPU virtual address. */
@@ -1223,6 +1153,39 @@ typedef union _gcuVIDMEM_NODE
         gctBOOL                 onFault;
     }
     Virtual;
+
+    struct _gcsVIDMEM_NODE_VIRTUAL_CHUNK
+    {
+        /* Owner of this chunk */
+        gckVIDMEM_BLOCK         parent;
+
+        /* Pointer to gckKERNEL object. */
+        gckKERNEL               kernel;
+
+        /* Dual-linked list of chunk. */
+        gcuVIDMEM_NODE_PTR      next;
+        gcuVIDMEM_NODE_PTR      prev;
+
+        /* Dual linked list of free chunk. */
+        gcuVIDMEM_NODE_PTR      nextFree;
+        gcuVIDMEM_NODE_PTR      prevFree;
+
+        /* Information for this chunk. */
+        gctSIZE_T               offset;
+        gctUINT32               addresses[gcvHARDWARE_NUM_TYPES];
+        gctINT32                lockeds[gcvHARDWARE_NUM_TYPES];
+        gctSIZE_T               bytes;
+
+        /* Mapped user logical */
+        gctPOINTER              logical;
+
+        /* Kernel virtual address. */
+        gctPOINTER              kvaddr;
+
+        /* Locked counter. */
+    }
+    VirtualChunk;
+
 }
 gcuVIDMEM_NODE;
 
@@ -1260,8 +1223,55 @@ struct _gckVIDMEM
     gctPOINTER                  mutex;
 };
 
+/* gckVIDMEM_BLOCK object. */
+typedef struct _gcsVIDMEM_BLOCK
+{
+    /* Object. */
+    gcsOBJECT                   object;
+
+    /* Pointer to gckOS object. */
+    gckOS                       os;
+
+    /* linked list of nodes. */
+    gckVIDMEM_BLOCK             next;
+
+    /* Contiguously allocated? */
+    gctBOOL                     contiguous;
+
+    /* Customer private handle */
+    gctUINT32                   gid;
+
+    /* mdl record pointer... a kmalloc address. Process agnostic. */
+    gctPHYS_ADDR                physical;
+
+    /* Information for this video memory virtual block. */
+    gctSIZE_T                   bytes;
+    gctSIZE_T                   freeBytes;
+
+    /* 1M page count. */
+    gctUINT32                   pageCount;
+
+    /* Gpu virtual base of this video memory heap. */
+    gctUINT32                   addresses[gcvHARDWARE_NUM_TYPES];
+    gctPOINTER                  pageTables[gcvHARDWARE_NUM_TYPES];
+
+    /* TODO: */
+    gceVIDMEM_TYPE              type;
+
+    /* Virtual chunk. */
+    gcuVIDMEM_NODE              node;
+
+    gctPOINTER                  mutex;
+
+    gctBOOL                     secure;
+    gctBOOL                     onFault;
+}
+gcsVIDMEM_BLOCK;
+
 typedef struct _gcsVIDMEM_NODE
 {
+    _VIV_VIDMEM_METADATA        metadata;
+
     /* Pointer to gcuVIDMEM_NODE. */
     gcuVIDMEM_NODE_PTR          node;
 
@@ -1363,9 +1373,25 @@ typedef struct _gcsDEVICE
     /* Same hardware type shares one MMU. */
     gckMMU                      mmus[gcvHARDWARE_NUM_TYPES];
 
-    gctUINT64                   sRAMBases[gcvCORE_COUNT][gcvSRAM_COUNT];
-    gctUINT32                   sRAMSizes[gcvCORE_COUNT][gcvSRAM_COUNT];
-    gctUINT32                   sRAMBaseAddresses[gcvCORE_COUNT][gcvSRAM_COUNT];
+    /* Physical address of internal SRAMs. */
+    gctUINT64                   sRAMBases[gcvCORE_COUNT][gcvSRAM_INTER_COUNT];
+    /* Internal SRAMs' size. */
+    gctUINT32                   sRAMSizes[gcvCORE_COUNT][gcvSRAM_INTER_COUNT];
+    /* GPU/VIP virtual address of internal SRAMs. */
+    gctUINT32                   sRAMBaseAddresses[gcvCORE_COUNT][gcvSRAM_INTER_COUNT];
+    gctBOOL                     sRAMPhysFaked[gcvCORE_COUNT][gcvSRAM_INTER_COUNT];
+
+    /* Physical address of external SRAMs. */
+    gctUINT64                   extSRAMBases[gcvSRAM_EXT_COUNT];
+    /* External SRAMs' size. */
+    gctUINT32                   extSRAMSizes[gcvSRAM_EXT_COUNT];
+    /* GPU/VIP virtual address of external SRAMs. */
+    gctUINT32                   extSRAMBaseAddresses[gcvSRAM_EXT_COUNT];
+    /* MDL. */
+    gctPHYS_ADDR                extSRAMPhysical[gcvSRAM_EXT_COUNT];
+
+    /* Show SRAM mapping info or not. */
+    gctUINT                     showSRAMMapInfo;
 
     /* Mutex to make sure stuck dump for multiple cores doesn't interleave. */
     gctPOINTER                  stuckDumpMutex;
@@ -1454,6 +1480,16 @@ gckVIDMEM_NODE_AllocateVirtual(
     OUT gckVIDMEM_NODE * NodeObject
     );
 
+gceSTATUS
+gckVIDMEM_NODE_AllocateVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
+    );
+
 gceSTATUS
 gckVIDMEM_NODE_Reference(
     IN gckKERNEL Kernel,
@@ -1638,6 +1674,8 @@ typedef struct _gcsADDRESS_AREA
     gctUINT32                   heapList;
     gctBOOL                     freeNodes;
 
+    gceAREA_TYPE                areaType;
+
     gctUINT32                   mappingStart;
     gctUINT32                   mappingEnd;
 
@@ -1691,7 +1729,8 @@ struct _gckMMU
 
     struct _gckQUEUE            recentFreedAddresses;
 
-    gcsADDRESS_AREA             dynamicArea;
+    gcsADDRESS_AREA             dynamicArea1M;
+    gcsADDRESS_AREA             dynamicArea4K;
     gcsADDRESS_AREA             secureArea;
 
     gctBOOL                     dynamicAreaSetuped;
@@ -1768,23 +1807,6 @@ gckKERNEL_AttachProcessEx(
     IN gctUINT32 PID
     );
 
-#if gcdSECURE_USER
-gceSTATUS
-gckKERNEL_MapLogicalToPhysical(
-    IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN OUT gctPOINTER * Data
-    );
-
-gceSTATUS
-gckKERNEL_FlushTranslationCache(
-    IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    );
-#endif
-
 gceSTATUS
 gckKERNEL_AllocateVideoMemory(
     IN gckKERNEL Kernel,
@@ -2146,7 +2168,8 @@ gckCOMMAND_Commit(
     IN gcsHAL_SUBCOMMIT * SubCommit,
     IN gctUINT32 ProcessId,
     IN gctBOOL Shared,
-    OUT gctUINT64_PTR CommitStamp
+    OUT gctUINT64_PTR CommitStamp,
+    INOUT gctBOOL *contextSwitched
     );
 
 /* Reserve space in the command buffer. */
index 834dc287ad32cbbeb81ee7cd765e6ffc97010a14..e1385f09fffad11f0a4b162d363d617c0626bd67 100644 (file)
@@ -234,132 +234,6 @@ OnError:
     return status;
 }
 
-#if gcdSECURE_USER
-static gceSTATUS
-_ProcessHints(
-    IN gckCOMMAND Command,
-    IN gctUINT32 ProcessID,
-    IN gcoCMDBUF CommandBuffer
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gckKERNEL kernel;
-    gctBOOL needCopy = gcvFALSE;
-    gcskSECURE_CACHE_PTR cache;
-    gctUINT8_PTR commandBufferLogical;
-    gctUINT8_PTR hintedData;
-    gctUINT32_PTR hintArray;
-    gctUINT i, hintCount;
-
-    gcmkHEADER_ARG(
-        "Command=0x%08X ProcessID=%d CommandBuffer=0x%08X",
-        Command, ProcessID, CommandBuffer
-        );
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
-
-    /* Reset state array pointer. */
-    hintArray = gcvNULL;
-
-    /* Get the kernel object. */
-    kernel = Command->kernel;
-
-    /* Get the cache form the database. */
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
-
-    /* Determine the start of the command buffer. */
-    commandBufferLogical
-        = (gctUINT8_PTR) CommandBuffer->logical
-        +                CommandBuffer->startOffset;
-
-    /* Determine the number of records in the state array. */
-    hintCount = CommandBuffer->hintArrayTail - CommandBuffer->hintArray;
-
-    /* Check wehther we need to copy the structures or not. */
-    gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
-
-    /* Get access to the state array. */
-    if (needCopy)
-    {
-        gctUINT copySize;
-
-        if (Command->hintArrayAllocated &&
-            (Command->hintArraySize < CommandBuffer->hintArraySize))
-        {
-            gcmkONERROR(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
-            Command->hintArraySize = gcvFALSE;
-        }
-
-        if (!Command->hintArrayAllocated)
-        {
-            gctPOINTER pointer = gcvNULL;
-
-            gcmkONERROR(gckOS_Allocate(
-                Command->os,
-                CommandBuffer->hintArraySize,
-                &pointer
-                ));
-
-            Command->hintArray          = gcmPTR_TO_UINT64(pointer);
-            Command->hintArrayAllocated = gcvTRUE;
-            Command->hintArraySize      = CommandBuffer->hintArraySize;
-        }
-
-        hintArray = gcmUINT64_TO_PTR(Command->hintArray);
-        copySize   = hintCount * gcmSIZEOF(gctUINT32);
-
-        gcmkONERROR(gckOS_CopyFromUserData(
-            Command->os,
-            hintArray,
-            gcmUINT64_TO_PTR(CommandBuffer->hintArray),
-            copySize
-            ));
-    }
-    else
-    {
-        gctPOINTER pointer = gcvNULL;
-
-        gcmkONERROR(gckOS_MapUserPointer(
-            Command->os,
-            gcmUINT64_TO_PTR(CommandBuffer->hintArray),
-            CommandBuffer->hintArraySize,
-            &pointer
-            ));
-
-        hintArray = pointer;
-    }
-
-    /* Scan through the buffer. */
-    for (i = 0; i < hintCount; i += 1)
-    {
-        /* Determine the location of the hinted data. */
-        hintedData = commandBufferLogical + hintArray[i];
-
-        /* Map handle into physical address. */
-        gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
-            kernel, cache, (gctPOINTER) hintedData
-            ));
-    }
-
-OnError:
-    /* Get access to the state array. */
-    if (!needCopy && (hintArray != gcvNULL))
-    {
-        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
-            Command->os,
-            gcmUINT64_TO_PTR(CommandBuffer->hintArray),
-            CommandBuffer->hintArraySize,
-            hintArray
-            ));
-    }
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
 static gceSTATUS
 _CheckFlushMMU(
     IN gckCOMMAND Command,
@@ -925,7 +799,7 @@ _CheckFlushMcfeMMU(
     gcmkONERROR(gckMCFE_WaitSemaphore(Hardware, buffer, id, &bytes));
 
     /* Execute flush mmu and send semaphores. */
-    gckCOMMAND_ExecuteMultiChannel(Command, 0, 0, reqBytes);
+    gcmkONERROR(gckCOMMAND_ExecuteMultiChannel(Command, 0, 0, reqBytes));
 
     /* Need sync from system channel. */
     Command->syncChannel[0] = ~1ull;
@@ -1752,15 +1626,6 @@ gckCOMMAND_Destroy(
         gcmkVERIFY_OK(gckOS_AtomDestroy(Command->os, Command->atomCommit));
     }
 
-#if gcdSECURE_USER
-    /* Free state array. */
-    if (Command->hintArrayAllocated)
-    {
-        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
-        Command->hintArrayAllocated = gcvFALSE;
-    }
-#endif
-
 #if gcdRECORD_COMMAND
     gckRECORDER_Destory(Command->os, Command->recorder);
 #endif
@@ -2309,7 +2174,8 @@ _CommitWaitLinkOnce(
     IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
     IN gcsSTATE_DELTA_PTR StateDelta,
     IN gctUINT32 ProcessID,
-    IN gctBOOL Shared
+    IN gctBOOL Shared,
+    INOUT gctBOOL *contextSwitched
     )
 {
     gceSTATUS status;
@@ -2390,15 +2256,23 @@ _CommitWaitLinkOnce(
                          + CommandBuffer->startOffset;
 
 #ifdef __QNXNTO__
-    userCommandBufferLogical = (gctPOINTER) commandBufferLogical;
+    gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+        Command->kernel,
+        ProcessID,
+        CommandBuffer->videoMemNode,
+        &commandBufferVideoMem
+        ));
 
-    gcmkONERROR(gckOS_MapUserPointer(
-        Command->os,
-        userCommandBufferLogical,
-        0,
-        (gctPOINTER *)&commandBufferLogical));
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+        Command->kernel,
+        commandBufferVideoMem,
+        gcvFALSE,
+        gcvFALSE,
+        &userCommandBufferLogical
+        ));
 
-    userCommandBufferLogicalMapped = gcvTRUE;
+    commandBufferLogical = (gctUINT8_PTR)userCommandBufferLogical + CommandBuffer->startOffset;
+    userCommandBufferLogicalMapped =gcvTRUE;
 #endif
 
     commandBufferSize = CommandBuffer->size;
@@ -2573,6 +2447,11 @@ _CommitWaitLinkOnce(
         /* Update the current context. */
         Command->currContext = Context;
 
+        if (contextSwitched)
+        {
+            *contextSwitched = gcvTRUE;
+        }
+
 #if gcdDUMP_IN_KERNEL
         contextDumpLogical = entryLogical;
 #endif
@@ -2634,11 +2513,6 @@ _CommitWaitLinkOnce(
 
     (void)entryLogical;
 
-#if gcdSECURE_USER
-    /* Process user hints. */
-    gcmkONERROR(_ProcessHints(Command, ProcessID, CommandBuffer));
-#endif
-
     /* Determine the location to jump to for the command buffer being
     ** scheduled. */
     if (Command->newQueue)
@@ -2977,15 +2851,16 @@ _CommitWaitLinkOnce(
     }
 
 #ifdef __QNXNTO__
-    if (userCommandBufferLogicalMapped)
+    if(userCommandBufferLogicalMapped)
     {
-        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
-            Command->os,
-            userCommandBufferLogical,
-            0,
-            commandBufferLogical));
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            Command->kernel,
+            commandBufferVideoMem,
+            ProcessID,
+            gcvFALSE
+            ));
 
-        userCommandBufferLogicalMapped = gcvFALSE;
+        userCommandBufferLogicalMapped =gcvFALSE;
     }
 #endif
 
@@ -3174,6 +3049,7 @@ OnError:
 static gceSTATUS
 _CommitMultiChannelOnce(
     IN gckCOMMAND Command,
+    IN gckCONTEXT Context,
     IN gcsHAL_COMMAND_LOCATION * CommandBuffer
     )
 {
@@ -3251,6 +3127,8 @@ _CommitMultiChannelOnce(
             ));
     }
 
+    Command->currContext = Context;
+
     gckOS_AcquireMutex(Command->os, Command->mutexQueue, gcvINFINITE);
     acquired = gcvTRUE;
 
@@ -3327,8 +3205,8 @@ OnError:
 **          Current process ID.
 **
 **  OUTPUT:
-**
-**      Nothing.
+**      gctBOOL *contextSwitched
+**          pass context Switch flag to upper
 */
 gceSTATUS
 gckCOMMAND_Commit(
@@ -3336,7 +3214,8 @@ gckCOMMAND_Commit(
     IN gcsHAL_SUBCOMMIT * SubCommit,
     IN gctUINT32 ProcessId,
     IN gctBOOL Shared,
-    OUT gctUINT64_PTR CommitStamp
+    OUT gctUINT64_PTR CommitStamp,
+    INOUT gctBOOL *contextSwitched
     )
 {
     gceSTATUS status;
@@ -3405,11 +3284,12 @@ gckCOMMAND_Commit(
                                          cmdLoc,
                                          delta,
                                          ProcessId,
-                                         Shared);
+                                         Shared,
+                                         contextSwitched);
         }
         else if (Command->feType == gcvHW_FE_MULTI_CHANNEL)
         {
-            status = _CommitMultiChannelOnce(Command, cmdLoc);
+            status = _CommitMultiChannelOnce(Command, context, cmdLoc);
         }
         else
         {
@@ -4220,14 +4100,45 @@ gckCOMMAND_Attach(
     IN gctUINT32 ProcessID
     )
 {
+    gctUINT32 allocationSize;
+    gctPOINTER pointer;
+    gceSTATUS status;
+
     if (Command->feType == gcvHW_FE_WAIT_LINK)
     {
-        return _AttachWaitLinkFECommand(Command,
+        status = _AttachWaitLinkFECommand(Command,
                                         Context,
                                         MaxState,
                                         NumStates,
                                         ProcessID);
     }
+    else if (Command->feType == gcvHW_FE_MULTI_CHANNEL)
+    {
+        /*
+         * For mcfe, we only allocate context which is used to
+         * store profile counters.
+         */
+        allocationSize = gcmSIZEOF(struct _gckCONTEXT);
+
+        /* Allocate the object. */
+        gckOS_Allocate(Command->os, allocationSize, &pointer);
+        if (!pointer)
+        {
+            return gcvSTATUS_OUT_OF_MEMORY;
+        }
+        *Context = pointer;
+        /* Reset the entire object. */
+        gckOS_ZeroMemory(*Context, allocationSize);
+
+        /* Initialize the gckCONTEXT object. */
+        (*Context)->object.type = gcvOBJ_CONTEXT;
+        (*Context)->os          = Command->os;
+        (*Context)->hardware    = Command->kernel->hardware;
+        *MaxState  = 0;
+        *NumStates = 0;
+
+        status = gcvSTATUS_OK;
+    }
     else
     {
         /* Nothing to do. */
@@ -4235,8 +4146,10 @@ gckCOMMAND_Attach(
         *MaxState  = 0;
         *NumStates = 0;
 
-        return gcvSTATUS_OK;
+        status = gcvSTATUS_OK;
     }
+
+    return status;
 }
 #endif
 
@@ -4319,6 +4232,11 @@ gckCOMMAND_Detach(
     {
         return _DetachWaitLinkFECommand(Command, Context);
     }
+    else if (Command->feType == gcvHW_FE_MULTI_CHANNEL)
+    {
+        gcmkOS_SAFE_FREE(Context->os, Context);
+        return gcvSTATUS_OK;
+    }
     else
     {
         /* Nothing to do. */
@@ -4453,7 +4371,7 @@ gckCOMMAND_DumpExecutingBuffer(
         gpuAddress &= 0xfffff000;
 
         /* Dump max 4096 bytes. */
-        bytes = (bytes - offset) > 1024 ? 1024 : (bytes - offset);
+        bytes = (bytes - offset) > 4096 ? 4096 : (bytes - offset);
 
         /* Kernel address of page where stall point stay. */
         entryDump = (gctUINT8_PTR)entryDump + offset;
index 128958df98903e19c23f90ed7cb1d4f28472b280..5c7443066b8ce085b0fe5c527c09d56f0f5d58bf 100644 (file)
@@ -646,53 +646,6 @@ gckKERNEL_CreateProcessDB(
     gcmkASSERT(database->handleDatabaseMutex == gcvNULL);
     gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->handleDatabaseMutex));
 
-#if gcdSECURE_USER
-    {
-        gctINT idx;
-        gcskSECURE_CACHE * cache = &database->cache;
-
-        /* Setup the linked list of cache nodes. */
-        for (idx = 1; idx <= gcdSECURE_CACHE_SLOTS; ++idx)
-        {
-            cache->cache[idx].logical = gcvNULL;
-
-#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
-            cache->cache[idx].prev = &cache->cache[idx - 1];
-            cache->cache[idx].next = &cache->cache[idx + 1];
-#   endif
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-            cache->cache[idx].nextHash = gcvNULL;
-            cache->cache[idx].prevHash = gcvNULL;
-#   endif
-        }
-
-#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
-        /* Setup the head and tail of the cache. */
-        cache->cache[0].next    = &cache->cache[1];
-        cache->cache[0].prev    = &cache->cache[gcdSECURE_CACHE_SLOTS];
-        cache->cache[0].logical = gcvNULL;
-
-        /* Fix up the head and tail pointers. */
-        cache->cache[0].next->prev = &cache->cache[0];
-        cache->cache[0].prev->next = &cache->cache[0];
-#   endif
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-        /* Zero out the hash table. */
-        for (idx = 0; idx < gcmCOUNTOF(cache->hash); ++idx)
-        {
-            cache->hash[idx].logical  = gcvNULL;
-            cache->hash[idx].nextHash = gcvNULL;
-        }
-#   endif
-
-        /* Initialize cache index. */
-        cache->cacheIndex = gcvNULL;
-        cache->cacheFree  = 1;
-        cache->cacheStamp = 0;
-    }
-#endif
-
     /* Insert the database into the hash. */
     database->next = Kernel->db->db[slot];
     Kernel->db->db[slot] = database;
@@ -1553,58 +1506,6 @@ OnError:
     return status;
 }
 
-#if gcdSECURE_USER
-/*******************************************************************************
-**  gckKERNEL_GetProcessDBCache
-**
-**  Get teh secure cache from a process database.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to a gckKERNEL object.
-**
-**      gctUINT32 ProcessID
-**          Process ID used to identify the database.
-**
-**  OUTPUT:
-**
-**      gcskSECURE_CACHE_PTR * Cache
-**          Pointer to a variable that receives the secure cache pointer.
-*/
-gceSTATUS
-gckKERNEL_GetProcessDBCache(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    OUT gcskSECURE_CACHE_PTR * Cache
-    )
-{
-    gceSTATUS status;
-    gcsDATABASE_PTR database;
-
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(Cache != gcvNULL);
-
-    /* Find the database. */
-    gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
-
-    /* Return the pointer to the cache. */
-    *Cache = &database->cache;
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Cache=0x%x", *Cache);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
 gceSTATUS
 gckKERNEL_DumpProcessDB(
     IN gckKERNEL Kernel
index d844aa1592d2b751e43d3de87143fb52cd33dc8a..474fd12dbbbedb5eea49083b7003770bf55af933 100644 (file)
@@ -66,7 +66,7 @@ static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
 _debugZones config value
 Please Reference define in gc_hal_base.h
 */
-static gctUINT32 _debugZones = gcvZONE_NONE;
+static gctUINT32 _debugZones = gcdZONE_NONE;
 
 /******************************************************************************\
 ********************************* Debug Switches *******************************
@@ -461,6 +461,12 @@ extern volatile unsigned g_nQnxInIsrs;
     atomic_sub(&g_nQnxInIsrs, 1); \
 }
 
+#elif defined(__VXWORKS__)
+#define gcmDEBUGPRINT(Message) \
+{ \
+    printf(Message); \
+}
+
 #else
 
 #define gcmDEBUGPRINT(Message) \
@@ -1074,7 +1080,6 @@ _DumpDataBuffer(
     gctSIZE_T length = 0;
     gctBOOL needCopy = gcvTRUE;
     gctCONST_STRING dumpTag;
-    gctBOOL skip = gcvFALSE;
     char buffer[256];
     const gctSIZE_T maxLength = gcmSIZEOF(_dumpStorage);
 
@@ -1123,12 +1128,6 @@ _DumpDataBuffer(
         gctSIZE_T count, tailByteCount;
 
         length = maxLength < (Size - offset) ? maxLength : (Size - offset);
-
-        if (skip)
-        {
-            length = 128 < length ? 128 : length;
-        }
-
         count = length / 4;
         tailByteCount = length % 4;
 
@@ -1235,20 +1234,6 @@ _DumpDataBuffer(
         {
             gckOS_UnmapUserPointer(Os, Data, length, data);
         }
-
-        if (skip && Size > 128 * 2)
-        {
-            length = (Size & ~(128 - 1)) - 128;
-            gcmkDUMP_STRING(Os, "  ...skip...\n");
-
-            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
-                        "  0x%08X:\n",
-                        (gctUINT32)(Address + length));
-            gcmkDUMP_STRING(Os, buffer);
-
-            skip = gcvFALSE;
-        }
-
         /* advance to next batch. */
         Data    = (gctUINT8_PTR)Data + length;
         offset += length;
index e83fe98326cd377ffc22fa7ff2533404c74ed3ab..76a33053a03489330163a17e6706e0568701597e 100644 (file)
@@ -730,7 +730,6 @@ gckEVENT_GetEvent(
     gctINT i, id;
     gceSTATUS status;
     gctBOOL acquired = gcvFALSE;
-    gctINT32 free;
 
     gcmkHEADER_ARG("Event=0x%x Source=%d", Event, Source);
 
@@ -765,18 +764,15 @@ gckEVENT_GetEvent(
                 Event->queues[id].source = Source;
 
                 /* Decrease the number of free events. */
-                free = --Event->freeQueueCount;
-
-                /* Make compiler happy. */
-                free = free;
+                --Event->freeQueueCount;
 
 #if gcdDYNAMIC_SPEED
-                if (free <= gcdDYNAMIC_EVENT_THRESHOLD)
+                if (Event->freeQueueCount <= gcdDYNAMIC_EVENT_THRESHOLD)
                 {
                     gcmkONERROR(gckOS_BroadcastHurry(
                         Event->os,
                         Event->kernel->hardware,
-                        gcdDYNAMIC_EVENT_THRESHOLD - free));
+                        gcdDYNAMIC_EVENT_THRESHOLD - Event->freeQueueCount));
                 }
 #endif
 
@@ -1718,10 +1714,6 @@ gckEVENT_Notify(
 
 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
     gctINT eventNumber = 0;
-#endif
-#if gcdSECURE_USER
-    gcskSECURE_CACHE_PTR cache;
-    gcuVIDMEM_NODE_PTR node;
 #endif
     gckVIDMEM_NODE nodeObject;
 
@@ -1927,10 +1919,6 @@ gckEVENT_Notify(
 #ifndef __QNXNTO__
             gctPOINTER logical;
 #endif
-#if gcdSECURE_USER
-            gctSIZE_T bytes;
-#endif
-
             /* Grab next record. */
             recordNext = record->next;
 
@@ -1941,14 +1929,6 @@ gckEVENT_Notify(
              */
             drv_thread_specific_key_assign(record->processID, 0);
 #endif
-
-#if gcdSECURE_USER
-            /* Get the cache that belongs to this process. */
-            gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel,
-                        record->processID,
-                        &cache));
-#endif
-
             gcmkTRACE_ZONE_N(
                 gcvLEVEL_INFO, gcvZONE_EVENT,
                 gcmSIZEOF(record->info.command),
@@ -1994,23 +1974,6 @@ gckEVENT_Notify(
 
                 nodeObject = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
 
-#if gcdSECURE_USER
-                node = nodeObject->node;
-
-                /* Save node information before it disappears. */
-                node = event->event.u.UnlockVideoMemory.node;
-                if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
-                {
-                    logical = gcvNULL;
-                    bytes   = 0;
-                }
-                else
-                {
-                    logical = node->Virtual.logical;
-                    bytes   = node->Virtual.bytes;
-                }
-#endif
-
                 /* Unlock, sync'ed. */
                 status = gckVIDMEM_NODE_Unlock(
                     Event->kernel,
@@ -2019,17 +1982,6 @@ gckEVENT_Notify(
                     gcvNULL
                     );
 
-#if gcdSECURE_USER
-                if (gcmIS_SUCCESS(status) && (logical != gcvNULL))
-                {
-                    gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
-                        Event->kernel,
-                        cache,
-                        logical,
-                        bytes));
-                }
-#endif
-
                 /* Deref node. */
                 status = gckVIDMEM_NODE_Dereference(Event->kernel, nodeObject);
                 break;
@@ -2410,14 +2362,22 @@ gckEVENT_Dump(
 
     if (Event->kernel->recovery == 0)
     {
-        gckOS_ReadRegisterEx(
-            Event->os,
-            Event->kernel->core,
-            0x10,
-            &intrAcknowledge
-            );
+        gceSTATUS status;
 
-        gcmkPRINT("  INTR_ACKNOWLEDGE=0x%x", intrAcknowledge);
+        status = gckOS_ReadRegisterEx(
+                    Event->os,
+                    Event->kernel->core,
+                    0x10,
+                    &intrAcknowledge
+                    );
+        if (gcmIS_ERROR(status))
+        {
+            gcmkPRINT("  READ INTR_ACKNOWLEDGE ERROR!");
+        }
+        else
+        {
+            gcmkPRINT("  INTR_ACKNOWLEDGE=0x%x", intrAcknowledge);
+        }
     }
 #endif
 
index 8aa27abd62c3e99cd9da7406d3a33a6db1e52344..325cdd74c733c4b9ad128aa860f7fb45fc3e8c19 100644 (file)
@@ -886,7 +886,3 @@ gckHEAP_ProfileEnd(
 }
 #endif /* VIVANTE_PROFILER_SYSTEM_MEMORY */
 
-/*******************************************************************************
-***** Test Code ****************************************************************
-*******************************************************************************/
-
index 427b51cfc8fdff7deec134bb1703c9e0c62a1938..60da4eba708e585186683c956e2bec5a1840b34b 100644 (file)
@@ -67,6 +67,10 @@ typedef enum _gceMMU_TYPE
 }
 gceMMU_TYPE;
 
+/* VIP SRAM start virtual address. */
+#define gcdRESERVE_START (4 << 20)
+#define gcdRESERVE_ALIGN (4 << 10)
+
 #define gcmENTRY_TYPE(x) (x & 0xF0)
 
 #define gcmENTRY_COUNT(x) ((x & 0xFFFFFF00) >> 8)
@@ -354,10 +358,14 @@ _AddressToIndex(
     IN gctUINT32 Address
     )
 {
+
+    gctUINT32 stlbShift = (Area->areaType == gcvAREA_TYPE_1M) ? gcdMMU_STLB_1M_SHIFT : gcdMMU_STLB_4K_SHIFT;
+    gctUINT32 stlbMask  = (Area->areaType == gcvAREA_TYPE_1M) ? gcdMMU_STLB_1M_MASK : gcdMMU_STLB_4K_MASK;
+    gctUINT32 stlbEntryNum = (Area->areaType == gcvAREA_TYPE_1M) ? gcdMMU_STLB_1M_ENTRY_NUM : gcdMMU_STLB_4K_ENTRY_NUM;
     gctUINT32 mtlbOffset = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
-    gctUINT32 stlbOffset = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+    gctUINT32 stlbOffset = (Address & stlbMask) >> stlbShift;
 
-    return (mtlbOffset - Area->mappingStart) * gcdMMU_STLB_4K_ENTRY_NUM + stlbOffset;
+    return (mtlbOffset - Area->mappingStart) * stlbEntryNum + stlbOffset;
 }
 
 static gctUINT32_PTR
@@ -638,7 +646,7 @@ _FillFlatMapping(
     gctUINT32 mtlb;
     gctUINT32 physBase;
     gckKERNEL kernel = Mmu->hardware->kernel;
-    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea;
+    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea4K;
     gctBOOL physicalRangeOverlapped = gcvFALSE;
     gctBOOL virtualRangeOverlapped = gcvFALSE;
     gctBOOL specificFlatMapping = gcvFALSE;
@@ -730,7 +738,7 @@ _FillFlatMapping(
      */
     if (!needShiftMapping)
     {
-        flatVirtualBase = reqVirtualBase ? reqVirtualBase : (gctUINT32) flatBase;
+        flatVirtualBase = reqVirtualBase ? reqVirtualBase : (gctUINT32)flatBase;
     }
 
     for (i = 0; i < Mmu->gpuAddressRangeCount; i++)
@@ -761,9 +769,10 @@ _FillFlatMapping(
     specificFlatMapping = (reqVirtualBase && !virtualRangeOverlapped && !physicalRangeOverlapped);
 
     /************************ Setup flat mapping in dynamic range. ****************/
-
     if (area->mappingStart != gcvINVALID_ADDRESS && mtlb >= area->mappingStart && mtlb < area->mappingEnd)
     {
+        /* This path is useless now, keep it 4K page size */
+
         gctUINT32_PTR stlbEntry;
 
         stlbEntry = _StlbEntry(area, physBase);
@@ -799,8 +808,10 @@ _FillFlatMapping(
                      physBase, physBase - 1 + flatSize);
 
             gcmkDUMP(Mmu->os,
-                     "@[physical.step 0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X",
-                     physical, data, flatSize / gcdMMU_PAGE_4K_SIZE * sizeof(gctUINT32), step, mask);
+                     "@[physical.step 0x%010llX 0x%08X 0x%08lX 0x%08X 0x%08X",
+                     (unsigned long long)physical, data,
+                     (unsigned long)(flatSize / gcdMMU_PAGE_4K_SIZE * sizeof(gctUINT32)),
+                     step, mask);
         }
 #endif
 
@@ -945,11 +956,13 @@ _FillFlatMapping(
             allocFlag |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
+            allocFlag |= gcvALLOC_FLAG_4GB_ADDR;
+
             gcmkONERROR(gckKERNEL_AllocateVideoMemory(
                 kernel,
                 gcdMMU_STLB_1M_SIZE,
                 gcvVIDMEM_TYPE_COMMAND,
-                allocFlag,
+                allocFlag | gcvALLOC_FLAG_4K_PAGES,
                 &newStlbChunk->size,
                 &pool,
                 &newStlbChunk->videoMem));
@@ -1020,8 +1033,9 @@ _FillFlatMapping(
 
                 gcmkDUMP(Mmu->os, "#[mmu-mtlb: flat-mapping, slot: %d]", mStart);
 
-                gcmkDUMP(Mmu->os, "@[physical.fill 0x%010X 0x%08X 0x%08X]",
-                         Mmu->mtlbPhysical + mStart * 4, Mmu->mtlbLogical[mStart], 4);
+                gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                         (unsigned long long)Mmu->mtlbPhysical + mStart * 4,
+                         Mmu->mtlbLogical[mStart], 4);
 
                 ++stlbIndex;
             }
@@ -1100,7 +1114,8 @@ _FillFlatMapping(
 
                 gcmkDUMP(Mmu->os,
                          "@[physical.step 0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X]",
-                         stlbPhyBase + i * 4, data, (last - i) * 4, step, mask);
+                         (unsigned long long)stlbPhyBase + i * 4,
+                         data, (last - i) * 4, step, mask);
             }
 #endif
 
@@ -1162,7 +1177,6 @@ _FillFlatMapping(
 
         gcmkASSERT(Mmu->gpuAddressRangeCount <= gcdMAX_FLAT_MAPPING_COUNT);
 
-
         return gcvSTATUS_OK;
 OnError:
         /* Roll back the allocation.
@@ -1199,9 +1213,11 @@ _SetupAddressArea(
 {
     gceSTATUS status;
     gctUINT32_PTR map;
+    gctUINT32 stlbSize = (Area->areaType == gcvAREA_TYPE_1M)
+                       ? gcdMMU_STLB_1M_SIZE : gcdMMU_STLB_4K_SIZE;
 
     gcmkHEADER();
-    Area->stlbSize = NumMTLBEntries * gcdMMU_STLB_4K_SIZE;
+    Area->stlbSize = NumMTLBEntries * stlbSize;
 
     gcmkSAFECASTSIZET(Area->stlbEntries, Area->stlbSize / gcmSIZEOF(gctUINT32));
 
@@ -1222,131 +1238,123 @@ OnError:
     return status;
 }
 
-gceSTATUS
-gckMMU_SetupDynamicSpace(
-    IN gckMMU Mmu
+static gceSTATUS
+_ConstructDynamicStlb(
+    IN gckMMU Mmu,
+    IN gcsADDRESS_AREA_PTR Area,
+    IN gctUINT32 NumEntries
     )
 {
-    gceSTATUS status;
-    gcsFreeSpaceNode_PTR nodeArray = gcvNULL;
-    gctINT i, nodeArraySize = 0;
-    gctUINT32 address;
-    gctINT numEntries = 0;
+    gceSTATUS status = gcvSTATUS_OK;
     gctBOOL acquired = gcvFALSE;
-    gctUINT32 mtlbEntry;
     gckKERNEL kernel = Mmu->hardware->kernel;
-    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea;
-    gcePOOL pool = gcdMMU_PGTABLE_POOL;
     gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
-
-    /* Find all the free address space. */
-    gcmkONERROR(_CollectFreeSpace(Mmu, &nodeArray, &nodeArraySize));
-
-    for (i = 0; i < nodeArraySize; i++)
-    {
-        if (nodeArray[i].entries > numEntries)
-        {
-            area->mappingStart = nodeArray[i].start;
-            numEntries         = nodeArray[i].entries;
-            area->mappingEnd   = area->mappingStart + numEntries;
-        }
-    }
-
-    gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
-
-#if gcdENABLE_TRUST_APPLICATION
-    if (gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_SECURITY) == gcvSTATUS_TRUE)
-    {
-        /* Setup secure address area when needed. */
-        gctUINT32 secureAreaSize = gcdMMU_SECURE_AREA_SIZE;
-        gcsADDRESS_AREA_PTR secureArea = &Mmu->secureArea;
-
-        gcmkASSERT(numEntries > (gctINT)secureAreaSize);
-
-        secureArea->mappingStart = area->mappingStart
-                                 + (numEntries - secureAreaSize);
-
-        gcmkONERROR(_SetupAddressArea(Mmu->os, secureArea, secureAreaSize));
-
-        numEntries -= secureAreaSize;
-    }
-#endif
-
-    /* Setup normal address area. */
-    gcmkONERROR(_SetupAddressArea(Mmu->os, area, numEntries));
+    gcePOOL pool = gcdMMU_PGTABLE_POOL;
+    gctUINT32 address;
+    gctUINT32 mtlbEntry;
+    gctUINT32 i;
 
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
     allocFlag |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
+    allocFlag |= gcvALLOC_FLAG_4GB_ADDR;
+
     /* Construct Slave TLB. */
     gcmkONERROR(gckKERNEL_AllocateVideoMemory(
                 kernel,
                 64,
                 gcvVIDMEM_TYPE_COMMAND,
-                allocFlag,
-                &area->stlbSize,
+                allocFlag | gcvALLOC_FLAG_4K_PAGES,
+                &Area->stlbSize,
                 &pool,
-                &area->stlbVideoMem));
+                &Area->stlbVideoMem));
 
     /* Lock for kernel side CPU access. */
     gcmkONERROR(gckVIDMEM_NODE_LockCPU(
                 kernel,
-                area->stlbVideoMem,
+                Area->stlbVideoMem,
                 gcvFALSE,
                 gcvFALSE,
-                (gctPOINTER *)&area->stlbLogical));
+                (gctPOINTER *)&Area->stlbLogical));
 
 #if gcdUSE_MMU_EXCEPTION
-    gcmkONERROR(_FillPageTable(area->stlbLogical,
-                               area->stlbEntries,
+    gcmkONERROR(_FillPageTable(Area->stlbLogical,
+                               Area->stlbEntries,
                                /* Enable exception */
                                1 << 1));
 #else
     /* Invalidate all entries. */
-    gcmkONERROR(gckOS_ZeroMemory(area->stlbLogical,
-                area->stlbSize));
+    gcmkONERROR(gckOS_ZeroMemory(Area->stlbLogical,
+                Area->stlbSize));
 #endif
 
     /* Get stlb table physical. */
     gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
                 kernel,
-                area->stlbVideoMem,
+                Area->stlbVideoMem,
                 0,
-                &area->stlbPhysical));
+                &Area->stlbPhysical));
 
     gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Mmu->os,
-                  area->stlbPhysical,
-                  &area->stlbPhysical));
-
+                  Area->stlbPhysical,
+                  &Area->stlbPhysical));
 
-    gcmkDUMP(Mmu->os, "#[mmu: dynamic space: 0x%08X - 0x%08X]",
-             (area->mappingStart << gcdMMU_MTLB_SHIFT),
-             (area->mappingEnd << gcdMMU_MTLB_SHIFT) - 1);
+    if (Area->areaType == gcvAREA_TYPE_1M)
+    {
+        gcmkDUMP(Mmu->os, "#[mmu: 1M page size dynamic space: 0x%08X - 0x%08X]",
+                 (Area->mappingStart << gcdMMU_MTLB_SHIFT),
+                 (Area->mappingEnd << gcdMMU_MTLB_SHIFT) - 1);
+    }
+    else
+    {
+        gcmkDUMP(Mmu->os, "#[mmu: 4K page size dynamic space: 0x%08X - 0x%08X]",
+                 (Area->mappingStart << gcdMMU_MTLB_SHIFT),
+                 (Area->mappingEnd << gcdMMU_MTLB_SHIFT) - 1);
+    }
 
     gcmkDUMP(Mmu->os, "#[mmu-stlb]");
 
-    gcmkDUMP(Mmu->os, "@[physical.fill 0x%010X 0x%08X 0x%08X]",
-             area->stlbPhysical, area->stlbLogical[0], area->stlbSize / 4);
+    gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+             (unsigned long long)Area->stlbPhysical,
+             Area->stlbLogical[0],
+             (unsigned long)Area->stlbSize);
 
-    gcmkSAFECASTPHYSADDRT(address, area->stlbPhysical);
+    gcmkSAFECASTPHYSADDRT(address, Area->stlbPhysical);
 
     /* Grab the mutex. */
     gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
     acquired = gcvTRUE;
 
     /* Map to Master TLB. */
-    for (i = (gctINT)area->mappingStart;
-         i < (gctINT)area->mappingStart + numEntries;
+    for (i = Area->mappingStart;
+         i < Area->mappingStart + NumEntries;
          i++)
     {
-        mtlbEntry = address
-                  /* 4KB page size */
-                  | (0 << 2)
-                  /* Ignore exception */
-                  | (0 << 1)
-                  /* Present */
-                  | (1 << 0);
+        if (Area->areaType == gcvAREA_TYPE_1M)
+        {
+            mtlbEntry = address
+                      /* 1M page size */
+                      | (1 << 3)
+                      /*Ignore exception */
+                      | (0 << 1)
+                      /* Present */
+                      | (1 << 0);
+
+            address += gcdMMU_STLB_1M_SIZE;
+        }
+        else
+        {
+            mtlbEntry = address
+                      /* 4KB page size */
+                      | (0 << 2)
+                      /*Ignore exception */
+                      | (0 << 1)
+                      /* Present */
+                      | (1 << 0);
+
+            address += gcdMMU_STLB_4K_SIZE;
+        }
 
         _WritePageEntry(Mmu->mtlbLogical + i, mtlbEntry);
 
@@ -1356,51 +1364,139 @@ gckMMU_SetupDynamicSpace(
                 i,
                 _ReadPageEntry(Mmu->mtlbLogical + i));
 #endif
-        address += gcdMMU_STLB_4K_SIZE;
     }
 
     gcmkDUMP(Mmu->os, "#[mmu-mtlb: slot: %d - %d]",
-             area->mappingStart, area->mappingEnd - 1);
+             Area->mappingStart, Area->mappingEnd - 1);
 
 #if gcdDUMP_IN_KERNEL
     {
-        gctUINT32 data = Mmu->mtlbLogical[area->mappingStart] & ~0x3F;
+        gctUINT32 data = Mmu->mtlbLogical[Area->mappingStart] & ~0x3F;
         gctUINT32 step = 0;
-        gctUINT32 mask = Mmu->mtlbLogical[area->mappingStart] & 0x3F;
+        gctUINT32 mask = Mmu->mtlbLogical[Area->mappingStart] & 0x3F;
 
-        if (numEntries > 1)
+        if (NumEntries > 1)
         {
-            step = Mmu->mtlbLogical[area->mappingStart + 1]
-                 - Mmu->mtlbLogical[area->mappingStart];
+            step = Mmu->mtlbLogical[Area->mappingStart + 1]
+                 - Mmu->mtlbLogical[Area->mappingStart];
         }
 
         gcmkDUMP(Mmu->os,
                  "@[physical.step 0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X]",
-                 (unsigned long long)(Mmu->mtlbPhysical + area->mappingStart * 4),
-                 data, numEntries * 4, step, mask);
+                 (unsigned long long)(Mmu->mtlbPhysical + Area->mappingStart * 4),
+                 data, NumEntries * 4, step, mask);
     }
 #endif
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+OnError:
+    if (acquired)
+    {
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+    }
+
+    return status;
+}
+
+gceSTATUS
+gckMMU_SetupDynamicSpace(
+    IN gckMMU Mmu
+    )
+{
+    gceSTATUS status;
+    gcsFreeSpaceNode_PTR nodeArray = gcvNULL;
+    gctINT i, nodeArraySize = 0;
+    gctINT numEntries = 0;
+    gckKERNEL kernel = Mmu->hardware->kernel;
+    gcsADDRESS_AREA_PTR area4K = &Mmu->dynamicArea4K;
+#if gcdENABLE_GPU_1M_PAGE
+    gcsADDRESS_AREA_PTR area1M = &Mmu->dynamicArea1M;
+    gctINT numEntries1M;
+#endif
+
+    /* Find all the free address space. */
+    gcmkONERROR(_CollectFreeSpace(Mmu, &nodeArray, &nodeArraySize));
+
+    for (i = 0; i < nodeArraySize; i++)
+    {
+        if (nodeArray[i].entries > numEntries)
+        {
+            area4K->mappingStart = nodeArray[i].start;
+            numEntries           = nodeArray[i].entries;
+            area4K->mappingEnd   = area4K->mappingStart + numEntries - 1;
+        }
+    }
+
+    gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
+
+#if gcdENABLE_TRUST_APPLICATION
+    if (gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_SECURITY) == gcvSTATUS_TRUE)
+    {
+        /* Setup secure address area when needed. */
+        gctUINT32 secureAreaSize = gcdMMU_SECURE_AREA_SIZE;
+        gcsADDRESS_AREA_PTR secureArea = &Mmu->secureArea;
+
+        gcmkASSERT(numEntries > (gctINT)secureAreaSize);
+
+        secureArea->mappingStart = area4K->mappingStart
+                                 + (numEntries - secureAreaSize);
+
+        gcmkONERROR(_SetupAddressArea(Mmu->os, secureArea, secureAreaSize));
+
+        numEntries -= secureAreaSize;
+        area4K->mappingEnd -= secureAreaSize;
+    }
+#endif
+
+#if gcdENABLE_GPU_1M_PAGE
+    numEntries1M = numEntries >> 1;
+    area1M->mappingStart = area4K->mappingStart + (numEntries - numEntries1M);
+    area1M->mappingEnd   = area1M->mappingStart + numEntries1M - 1;
+    area1M->areaType     = gcvAREA_TYPE_1M;
+    numEntries           -= numEntries1M;
+    area4K->mappingEnd   -= numEntries1M;
+
+    gcmkONERROR(_SetupAddressArea(Mmu->os, area1M, numEntries1M));
+
+    gcmkONERROR(_ConstructDynamicStlb(Mmu, area1M, numEntries1M));
+#endif
+
+    area4K->areaType = gcvAREA_TYPE_4K;
+
+    /* Setup normal address area. */
+    gcmkONERROR(_SetupAddressArea(Mmu->os, area4K, numEntries));
+
+    gcmkONERROR(_ConstructDynamicStlb(Mmu, area4K, numEntries));
 
     return gcvSTATUS_OK;
 
 OnError:
-    if (area->mapLogical)
+#if gcdENABLE_GPU_1M_PAGE
+    if (area1M->mapLogical)
     {
         gcmkVERIFY_OK(
-            gckOS_Free(Mmu->os, (gctPOINTER) area->mapLogical));
+            gckOS_Free(Mmu->os, (gctPOINTER) area1M->mapLogical));
+    }
 
+    if (area1M->stlbVideoMem)
+    {
         gcmkVERIFY_OK(
             gckVIDMEM_NODE_Dereference(kernel,
-                                       area->stlbVideoMem));
+                                       area1M->stlbVideoMem));
     }
+#endif
 
-    if (acquired)
+    if (area4K->mapLogical)
     {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+        gcmkVERIFY_OK(
+            gckOS_Free(Mmu->os, (gctPOINTER) area4K->mapLogical));
+    }
+
+    if (area4K->stlbVideoMem)
+    {
+        gcmkVERIFY_OK(
+            gckVIDMEM_NODE_Dereference(kernel,
+                                       area4K->stlbVideoMem));
     }
 
     return status;
@@ -1426,6 +1522,7 @@ _GetPageCountOfUsedNode(
 static gcsADDRESS_AREA_PTR
 _GetProcessArea(
     IN gckMMU Mmu,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure
     )
 {
@@ -1436,7 +1533,14 @@ _GetProcessArea(
     }
 #endif
 
-    return &Mmu->dynamicArea;
+    if (PageType == gcvPAGE_TYPE_1M)
+    {
+        return &Mmu->dynamicArea1M;
+    }
+    else
+    {
+        return &Mmu->dynamicArea4K;
+    }
 }
 
 /*******************************************************************************
@@ -1520,7 +1624,8 @@ _Construct(
 
     gcsLIST_Init(&mmu->hardwareList);
 
-    area = &mmu->dynamicArea;
+    /* Use 4K page size for MMU version 0. */
+    area = &mmu->dynamicArea4K;
     area->mapLogical  = gcvNULL;
     area->stlbLogical = gcvNULL;
 
@@ -1585,9 +1690,14 @@ _Construct(
 
         _FillPageTable(area->stlbLogical, area->stlbEntries, mmu->safeAddress);
 
-        gcmkDUMP(mmu->os, "#[mmu0: fill with safe address]");
-        gcmkDUMP(mmu->os, "@[physical.fill 0x%010X 0x%08X 0x%08X]",
-                 area->stlbPhysical, area->stlbLogical[0], area->stlbSize / 4);
+        gcmkDUMP(mmu->os,
+                 "#[mmu0: fill with safe address]");
+
+        gcmkDUMP(mmu->os,
+                 "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+                 (unsigned long long)area->stlbPhysical,
+                 area->stlbLogical[0],
+                 (unsigned long)area->stlbSize);
 
         map[0] = (area->stlbEntries << 8) | gcvMMU_FREE;
         map[1] = ~0U;
@@ -1618,11 +1728,14 @@ _Construct(
         allocFlag |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
+        allocFlag |= gcvALLOC_FLAG_4GB_ADDR;
+
+        /* 1K mode is 1024 byte aligned. */
         gcmkONERROR(gckKERNEL_AllocateVideoMemory(
                     Kernel,
-                    4096,
+                    1024,
                     gcvVIDMEM_TYPE_COMMAND,
-                    allocFlag,
+                    allocFlag | gcvALLOC_FLAG_4K_PAGES,
                     &mmu->mtlbSize,
                     &pool,
                     &mmu->mtlbVideoMem));
@@ -1637,7 +1750,8 @@ _Construct(
 
         mmu->mtlbLogical = pointer;
 
-        area->mappingStart = gcvINVALID_ADDRESS;
+        mmu->dynamicArea4K.mappingStart = gcvINVALID_ADDRESS;
+        mmu->dynamicArea1M.mappingStart = gcvINVALID_ADDRESS;
 
         /* Get mtlb table physical. */
         gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
@@ -1673,7 +1787,6 @@ _Construct(
             gcmkONERROR(_FillFlatMapping(mmu, gpuAddress, physSize, gcvFALSE, gcvFALSE, gcvNULL));
         }
 
-#ifndef EMULATOR
         if (!_ReadPageEntry(mmu->mtlbLogical + 0))
         {
             gctUINT32 mtlbEntry;
@@ -1700,7 +1813,6 @@ _Construct(
             mmu->gpuAddressRanges[mmu->gpuAddressRangeCount].flag  = gcvFLATMAP_DIRECT;
             mmu->gpuAddressRangeCount++;
         }
-#endif
 
         status = gckOS_QueryOption(mmu->os, "contiguousBase", &contiguousBase);
 
@@ -1762,7 +1874,7 @@ _Construct(
         Kernel,
         256,
         gcvVIDMEM_TYPE_COMMAND,
-        gcvALLOC_FLAG_CONTIGUOUS,
+        gcvALLOC_FLAG_CONTIGUOUS | gcvALLOC_FLAG_4K_PAGES,
         &mmu->safePageSize,
         &pool,
         &mmu->safePageVideoMem
@@ -1796,17 +1908,18 @@ _Construct(
     gckOS_ZeroMemory(mmu->safePageLogical, mmu->safePageSize);
 
     gcmkDUMP(mmu->os, "#[safe page]");
-    gcmkDUMP(
-        mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
-        mmu->safePagePhysical, 0, 4096
-        );
+    gcmkDUMP(mmu->os,
+            "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+            (unsigned long long)mmu->safePagePhysical,
+            0,
+            (unsigned long)mmu->safePageSize);
 
     gcmkDUMP_BUFFER(
         mmu->os,
         gcvDUMP_BUFFER_KERNEL_COMMAND,
         mmu->safePageLogical,
         mmu->safeAddress,
-        4096
+        mmu->safePageSize
         );
 
     gcmkONERROR(gckQUEUE_Allocate(os, &mmu->recentFreedAddresses, 16));
@@ -1945,10 +2058,10 @@ _Destroy(
                      pre->mtlbIndex + pre->mtlbEntryNum - 1);
 
             gcmkDUMP(Mmu->os,
-                     "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
-                     Mmu->mtlbPhysical + pre->mtlbIndex * 4,
+                     "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+                     (unsigned long long)(Mmu->mtlbPhysical + pre->mtlbIndex * 4),
                      Mmu->mtlbLogical[pre->mtlbIndex],
-                     pre->mtlbEntryNum * 4);
+                     (unsigned long)(pre->mtlbEntryNum * 4));
         }
 
         gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
@@ -1962,7 +2075,10 @@ _Destroy(
     }
 
     /* Free address area. */
-    gcmkVERIFY_OK(_FreeAddressArea(kernel, &Mmu->dynamicArea));
+    gcmkVERIFY_OK(_FreeAddressArea(kernel, &Mmu->dynamicArea4K));
+#if gcdENABLE_GPU_1M_PAGE
+    gcmkVERIFY_OK(_FreeAddressArea(kernel, &Mmu->dynamicArea1M));
+#endif
     gcmkVERIFY_OK(_FreeAddressArea(kernel, &Mmu->secureArea));
 
     /* Delete the page table mutex. */
@@ -2006,7 +2122,7 @@ _AdjustIndex(
 {
     gceSTATUS status;
     gctUINT32 index = Index;
-    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea;
+    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea4K;
     gctUINT32_PTR map = area->mapLogical;
 
     gcmkHEADER();
@@ -2181,6 +2297,7 @@ _AllocatePages(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
     IN gceVIDMEM_TYPE Type,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
@@ -2193,7 +2310,7 @@ _AllocatePages(
     gctBOOL gotIt;
     gctUINT32 address;
     gctUINT32 pageCount;
-    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, Secure);
+    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, PageType, Secure);
 
     gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount);
 
@@ -2367,12 +2484,13 @@ _AllocatePages(
     }
     else
     {
-        gctUINT32 masterOffset = index / gcdMMU_STLB_4K_ENTRY_NUM
-                               + area->mappingStart;
-        gctUINT32 slaveOffset = index % gcdMMU_STLB_4K_ENTRY_NUM;
+        gctUINT32 num = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_ENTRY_NUM : gcdMMU_STLB_4K_ENTRY_NUM;
+        gctUINT32 shift = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_SHIFT : gcdMMU_STLB_4K_SHIFT;
+        gctUINT32 masterOffset = index / num + area->mappingStart;
+        gctUINT32 slaveOffset = index % num;
 
         address = (masterOffset << gcdMMU_MTLB_SHIFT)
-                | (slaveOffset << gcdMMU_STLB_4K_SHIFT);
+                | (slaveOffset << shift);
     }
 
     if (Address != gcvNULL)
@@ -2426,6 +2544,7 @@ gceSTATUS
 _FreePages(
     IN gckMMU Mmu,
     IN gctBOOL Secure,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctSIZE_T PageCount
@@ -2437,7 +2556,9 @@ _FreePages(
     gctBOOL acquired = gcvFALSE;
     gctUINT32 pageCount;
     gcuQUEUEDATA data;
-    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, Secure);
+    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, PageType, gcvFALSE);
+    gctUINT32 pageSize = (PageType == gcvPAGE_TYPE_1M)
+                       ? gcdMMU_PAGE_1M_SIZE : gcdMMU_PAGE_4K_SIZE;
 
     gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
                    Mmu, PageTable, PageCount);
@@ -2454,6 +2575,7 @@ _FreePages(
 
     /* Get the node by index. */
     index = (gctUINT32)((gctUINT32_PTR)PageTable - area->stlbLogical);
+
     node = area->mapLogical + index;
 
     if (pageCount != _GetPageCountOfUsedNode(node))
@@ -2505,18 +2627,22 @@ _FreePages(
         }
     }
 
-    gcmkDUMP(Mmu->os, "#[mmu-stlb: free 0x%08X - 0x%08X]",
-             Address, Address + pageCount * gcdMMU_PAGE_4K_SIZE - 1);
+    gcmkDUMP(Mmu->os,
+             "#[mmu-stlb: free 0x%08X - 0x%08X]",
+             Address, Address + pageCount * pageSize - 1);
 
-    gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
-             area->stlbPhysical + index * 4, *(gctUINT32_PTR)PageTable, pageCount * 4);
+    gcmkDUMP(Mmu->os,
+             "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+             (unsigned long long)(area->stlbPhysical + index * 4),
+             *(gctUINT32_PTR)PageTable,
+             pageCount * 4);
 
     /* We have free nodes. */
     area->freeNodes = gcvTRUE;
 
     /* Record freed address range. */
     data.addressData.start = Address;
-    data.addressData.end = Address + (gctUINT32)PageCount * gcdMMU_PAGE_4K_SIZE;
+    data.addressData.end = Address + (gctUINT32)PageCount * pageSize;
     gckQUEUE_Enqueue(&Mmu->recentFreedAddresses, &data);
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
@@ -2547,12 +2673,13 @@ gceSTATUS
 gckMMU_AllocatePages(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
+    IN gcePAGE_TYPE PageType,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
     )
 {
     return gckMMU_AllocatePagesEx(
-                Mmu, PageCount, gcvVIDMEM_TYPE_GENERIC, gcvFALSE, PageTable, Address);
+                Mmu, PageCount, gcvVIDMEM_TYPE_GENERIC, PageType, gcvFALSE, PageTable, Address);
 }
 
 gceSTATUS
@@ -2560,6 +2687,7 @@ gckMMU_AllocatePagesEx(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
     IN gceVIDMEM_TYPE Type,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
@@ -2569,7 +2697,7 @@ gckMMU_AllocatePagesEx(
     gcmkPRINT("GPU virtual address is disabled.");
     return gcvSTATUS_NOT_SUPPORTED;
 #else
-    return _AllocatePages(Mmu, PageCount, Type, Secure, PageTable, Address);
+    return _AllocatePages(Mmu, PageCount, Type, PageType, Secure, PageTable, Address);
 #endif
 }
 
@@ -2577,18 +2705,20 @@ gceSTATUS
 gckMMU_FreePages(
     IN gckMMU Mmu,
     IN gctBOOL Secure,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctSIZE_T PageCount
     )
 {
-    return _FreePages(Mmu, Secure, Address, PageTable, PageCount);
+    return _FreePages(Mmu, Secure, PageType, Address, PageTable, PageCount);
 }
 
 gceSTATUS
 gckMMU_SetPage(
     IN gckMMU Mmu,
     IN gctPHYS_ADDR_T PageAddress,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Writable,
     IN gctUINT32 *PageEntry
     )
@@ -2601,7 +2731,15 @@ gckMMU_SetPage(
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
     gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
-    gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
+
+    if (PageType == gcvPAGE_TYPE_1M)
+    {
+        gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFFFF));
+    }
+    else
+    {
+        gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
+    }
 
     /* [31:0]. */
     address    = (gctUINT32)(PageAddress & 0xFFFFFFFF);
@@ -2617,6 +2755,23 @@ gckMMU_SetPage(
         _WritePageEntry(PageEntry, _SetPage(address, addressExt, gcvTRUE));
     }
 
+#ifdef DUMP_IN_KERNEL
+    {
+        gctUINT32 *stlbLogical = (PageType == gcvPAGE_TYPE_1M)
+                               ? Mmu->dynamicArea1M.stlbLogical
+                               : Mmu->dynamicArea4K.stlbLogical;
+
+        gctPHYS_ADDR_T stlbPhysical = (PageType == gcvPAGE_TYPE_1M)
+                                    ? Mmu->dynamicArea1M.stlbPhysical
+                                    : Mmu->dynamicArea4K.stlbPhysical;
+
+        gctPHYS_ADDR_T physical = stlbPhysical + (stlbLogical - PageEntry) * 4;
+
+        gckDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 4",
+                physical, *PageEntry);
+    }
+#endif
+
     /* Success. */
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -2689,29 +2844,40 @@ gckMMU_Flush(
 gceSTATUS
 gckMMU_DumpPageTableEntry(
     IN gckMMU Mmu,
+    IN gceAREA_TYPE AreaType,
     IN gctUINT32 Address
     )
 {
     gctUINT32_PTR pageTable;
     gctUINT32 index;
     gctUINT32 mtlb, stlb;
-    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea;
+    gcsADDRESS_AREA_PTR area = (AreaType == gcvAREA_TYPE_4K)
+                             ? &Mmu->dynamicArea4K : &Mmu->dynamicArea1M;
+
+    gctUINT32 stlbShift = (AreaType == gcvAREA_TYPE_4K)
+                        ? gcdMMU_STLB_4K_SHIFT : gcdMMU_STLB_1M_SHIFT;
+
+    gctUINT32 stlbMask  = (AreaType == gcvAREA_TYPE_4K)
+                        ? gcdMMU_STLB_4K_MASK : gcdMMU_STLB_1M_MASK;
+
+    gctUINT32 stlbEntryNum = (AreaType == gcvAREA_TYPE_4K)
+                           ? gcdMMU_STLB_4K_ENTRY_NUM : gcdMMU_STLB_1M_ENTRY_NUM;
 
     gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
     gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
 
     gcmkASSERT(Mmu->hardware->mmuVersion > 0);
 
-    mtlb   = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+    mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
 
-    if (mtlb >= area->mappingStart)
+    if (AreaType != gcvAREA_TYPE_FLATMAP)
     {
-        stlb   = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+        stlb = (Address & stlbMask) >> stlbShift;
 
         pageTable = area->stlbLogical;
 
         index = (mtlb - area->mappingStart)
-              * gcdMMU_STLB_4K_ENTRY_NUM
+              * stlbEntryNum
               + stlb;
 
         gcmkPRINT("    Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
@@ -2785,7 +2951,8 @@ gckMMU_DumpAddressSpace(
 {
     gctUINT i;
     gctUINT next;
-    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea;
+    /* TODO: */
+    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea4K;
     gctUINT32_PTR map = area->mapLogical;
     gctBOOL used = gcvFALSE;
     gctUINT32 numPages;
@@ -2878,13 +3045,15 @@ OnError:
 gceSTATUS
 gckMMU_IsFlatMapped(
     IN gckMMU Mmu,
-    OUT gctUINT64 Physical,
+    IN gctUINT64 Physical,
+    IN gctUINT32 Address,
     OUT gctBOOL *In
     )
 {
     gceSTATUS status;
     gctUINT32 i;
     gctBOOL inFlatmapping = gcvFALSE;
+
     gcmkHEADER();
 
     gcmkVERIFY_ARGUMENT(In != gcvNULL);
@@ -2894,13 +3063,29 @@ gckMMU_IsFlatMapped(
         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
     }
 
-    for (i = 0; i < Mmu->gpuPhysicalRangeCount; i++)
+    if (Physical != gcvINVALID_PHYSICAL_ADDRESS)
     {
-        if ((Physical >= Mmu->gpuPhysicalRanges[i].start) &&
-            (Physical < Mmu->gpuPhysicalRanges[i].end))
+        for (i = 0; i < Mmu->gpuPhysicalRangeCount; i++)
         {
-            inFlatmapping = gcvTRUE;
-            break;
+            if ((Physical >= Mmu->gpuPhysicalRanges[i].start) &&
+                (Physical <= Mmu->gpuPhysicalRanges[i].end))
+            {
+                inFlatmapping = gcvTRUE;
+                break;
+            }
+        }
+    }
+
+    if (Address != gcvINVALID_ADDRESS)
+    {
+        for (i = 0; i < Mmu->gpuAddressRangeCount; i++)
+        {
+            if ((Address >= Mmu->gpuAddressRanges[i].start) &&
+                (Address <= Mmu->gpuAddressRanges[i].end))
+            {
+                inFlatmapping = gcvTRUE;
+                break;
+            }
         }
     }
 
@@ -2915,7 +3100,7 @@ OnError:
 }
 
 gceSTATUS
-gckMMU_SetupPerHardware(
+gckMMU_SetupSRAM(
     IN gckMMU Mmu,
     IN gckHARDWARE Hardware,
     IN gckDEVICE Device
@@ -2940,76 +3125,116 @@ gckMMU_SetupPerHardware(
 
     if (!Mmu->sRAMMapped)
     {
+        gctUINT32 address = gcvINVALID_ADDRESS;
+        gctUINT32 size    = 0;
+
         /* Map all the SRAMs in MMU table. */
         for (i = 0; i < gcvCORE_COUNT; i++)
         {
-            reservedBase = Device->sRAMBases[i][gcvSRAM_INTERNAL];
-            reservedSize = Device->sRAMSizes[i][gcvSRAM_INTERNAL];
-            needMapInternalSRAM = reservedSize && (reservedBase != gcvINVALID_PHYSICAL_ADDRESS);
+            for (j = gcvSRAM_INTERNAL0; j < gcvSRAM_INTER_COUNT; j++)
+            {
+                reservedBase = Device->sRAMBases[i][j];
+                reservedSize = Device->sRAMSizes[i][j];
+
+                needMapInternalSRAM = reservedSize && (reservedBase != gcvINVALID_PHYSICAL_ADDRESS);
+
+                /* Map the internal SRAM. */
+                if (needMapInternalSRAM)
+                {
+                    if (Device->showSRAMMapInfo)
+                    {
+                        gcmkPRINT("Galcore Info: MMU mapped core%d SRAM base=0x%llx size=0x%x",
+                            i,
+                            reservedBase,
+                            reservedSize
+                            );
+                    }
+
+                    /*
+                     * Default gpu virtual base = 0.
+                     * It can be specified if not conflict with existing mapping.
+                     */
+
+                    Device->sRAMBaseAddresses[i][j] = 0;
+
+                    gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(
+                        Mmu->os,
+                        reservedBase,
+                        &reservedBase
+                        ));
+
+                    gcmkONERROR(_FillFlatMapping(
+                        Mmu,
+                        reservedBase,
+                        reservedSize,
+                        gcvTRUE,
+                        gcvTRUE,
+                        &Device->sRAMBaseAddresses[i][j]
+                        ));
+
+                    Device->sRAMBases[i][j] = reservedBase;
+                }
+                else if (reservedSize && reservedBase == gcvINVALID_PHYSICAL_ADDRESS)
+                {
+                    /*
+                     * Reserve the internal SRAM range in first reserved MMU mtlb,
+                     * when CPU physical base address is not specified, which means it is reserve usage.
+                     */
+                    Device->sRAMBaseAddresses[i][j] = (address == gcvINVALID_ADDRESS) ? gcdRESERVE_START :
+                                                      address + gcmALIGN(size, gcdRESERVE_ALIGN);
+
+                    Device->sRAMBases[i][j] = address = Device->sRAMBaseAddresses[i][j];
+
+                    size = Device->sRAMSizes[i][j];
+
+                    Device->sRAMPhysFaked[i][j] = gcvTRUE;
+                }
 
-            /* Map the internal SRAM. */
-            if (needMapInternalSRAM)
+                Hardware->options.sRAMGPUVirtAddrs[j] = Device->sRAMBaseAddresses[i][j];
+            }
+        }
+
+        /* Map all the external SRAMs in MMU table. */
+        for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_EXT_COUNT; i++)
+        {
+            if (Device->extSRAMSizes[i] &&
+               (Device->extSRAMBases[i] != gcvINVALID_PHYSICAL_ADDRESS))
             {
-                gcmkPRINT("Galcore Info: MMU mapped core%d internal SRAM base=0x%llx size=0x%x",
-                    i,
-                    reservedBase,
-                    reservedSize
-                    );
 
-                /*
-                 * Default gpu virtual base = 0.
-                 * It can be specified if not conflict with existing mapping.
-                 */
+                Device->extSRAMBaseAddresses[i] = 0;
 
-                Device->sRAMBaseAddresses[i][gcvSRAM_INTERNAL] = 0;
+                Hardware->options.extSRAMCPUPhysAddrs[i] = Device->extSRAMBases[i];
 
                 gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(
                     Mmu->os,
-                    reservedBase,
-                    &reservedBase
+                    Device->extSRAMBases[i],
+                    &Device->extSRAMBases[i]
                     ));
 
+                Hardware->options.extSRAMGPUPhysAddrs[i] = Device->extSRAMBases[i];
+
                 gcmkONERROR(_FillFlatMapping(
                     Mmu,
-                    reservedBase,
-                    reservedSize,
-                    gcvTRUE,
+                    Device->extSRAMBases[i],
+                    Device->extSRAMSizes[i],
+                    gcvFALSE,
                     gcvTRUE,
-                    &Device->sRAMBaseAddresses[i][gcvSRAM_INTERNAL]
+                    &Device->extSRAMBaseAddresses[i]
                     ));
 
-                Device->sRAMBases[i][j] = reservedBase;
-            }
+                kernel->extSRAMBaseAddresses[i] = Device->extSRAMBaseAddresses[i];
 
-            /* Map all the axi SRAMs in MMU table. */
-            for (j = gcvSRAM_EXTERNAL0; j < gcvSRAM_COUNT; j++)
-            {
-                if (Device->sRAMSizes[i][j] &&
-                   (Device->sRAMBases[i][j] != gcvINVALID_PHYSICAL_ADDRESS))
+                Hardware->options.extSRAMGPUVirtAddrs[i] = Device->extSRAMBaseAddresses[i];
+                Hardware->options.extSRAMSizes[i] = Device->extSRAMSizes[i];
+
+                if (Device->showSRAMMapInfo)
                 {
-                    gcmkPRINT("Galcore Info: MMU mapped core %d SRAM[%d] base=0x%llx size=0x%x",
+                    gcmkPRINT("Galcore Info: MMU mapped external shared SRAM[%d] CPU base=0x%llx GPU virtual address=0x%x size=0x%x",
                         i,
-                        j,
-                        Device->sRAMBases[i][j],
-                        Device->sRAMSizes[i][j]
+                        Device->extSRAMBases[i],
+                        kernel->extSRAMBaseAddresses[i],
+                        Device->extSRAMSizes[i]
                         );
-
-                    Device->sRAMBaseAddresses[i][j] = 0;
-
-                    gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(
-                        Mmu->os,
-                        Device->sRAMBases[i][j],
-                        &Device->sRAMBases[i][j]
-                        ));
-
-                    gcmkONERROR(_FillFlatMapping(
-                        Mmu,
-                        Device->sRAMBases[i][j],
-                        Device->sRAMSizes[i][j],
-                        gcvFALSE,
-                        gcvTRUE,
-                        &Device->sRAMBaseAddresses[i][j]
-                        ));
                 }
             }
         }
@@ -3018,25 +3243,59 @@ gckMMU_SetupPerHardware(
     }
 
     /* Get per core SRAM hardware base address. */
-    for (i = 0; i < gcvSRAM_COUNT; i++)
+    for (i = gcvSRAM_INTERNAL0; i < gcvSRAM_INTER_COUNT; i++)
     {
         if (Device->sRAMSizes[Hardware->core][i] &&
            (Device->sRAMBases[Hardware->core][i] != gcvINVALID_PHYSICAL_ADDRESS))
         {
-            kernel->sRAMBaseAddresses[i] = Hardware->options.sRAMBaseAddresses[i]
-                                         = Device->sRAMBaseAddresses[Hardware->core][i];
-
+            kernel->sRAMBaseAddresses[i] = Device->sRAMBaseAddresses[Hardware->core][i];
             kernel->sRAMSizes[i] = Hardware->options.sRAMSizes[i]
                                  = Device->sRAMSizes[Hardware->core][i];
 
-            Hardware->options.sRAMPhysicalBases[i] = Device->sRAMBases[Hardware->core][i];
+            kernel->sRAMPhysFaked[i] = Device->sRAMPhysFaked[Hardware->core][i];
 
-            gcmkPRINT("Galcore Info: MMU mapped core %d SRAM[%d] hardware address=0x%x size=0x%x",
-                Hardware->core,
-                i,
-                kernel->sRAMBaseAddresses[i],
-                kernel->sRAMSizes[i]
-                );
+            /* If the internal SRAM usage is reserve. */
+            if (kernel->sRAMPhysFaked[i])
+            {
+                /* Use virtual address as the faked physical address which will never be accessed. */
+                status = gckVIDMEM_Construct(
+                    Mmu->os,
+                    (gctPHYS_ADDR_T)kernel->sRAMBaseAddresses[i],
+                    kernel->sRAMSizes[i],
+                    64,
+                    0,
+                    &kernel->sRAMVidMem[i]
+                    );
+
+                if (gcmIS_ERROR(status))
+                {
+                    kernel->sRAMSizes[i] = 0;
+                    kernel->sRAMVidMem[i] = gcvNULL;
+                }
+                else
+                {
+                    gcmkONERROR(gckOS_RequestReservedMemory(
+                        Mmu->os,
+                        (gctPHYS_ADDR_T)kernel->sRAMBaseAddresses[i],
+                        kernel->sRAMSizes[i],
+                        "Per core SRAM reserve usage region",
+                        gcvTRUE,
+                        &kernel->sRAMPhysical[i]
+                        ));
+
+                    kernel->sRAMVidMem[i]->physical = kernel->sRAMPhysical[i];
+                }
+            }
+
+            if (Device->showSRAMMapInfo)
+            {
+                gcmkPRINT("Galcore Info: MMU mapped core %d SRAM[%d] hardware virtual address=0x%x size=0x%x",
+                    Hardware->core,
+                    i,
+                    kernel->sRAMBaseAddresses[i],
+                    kernel->sRAMSizes[i]
+                    );
+            }
         }
     }
 
@@ -3055,31 +3314,34 @@ OnError:
 gceSTATUS
 gckMMU_GetPageEntry(
     IN gckMMU Mmu,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctUINT32_PTR *PageTable
     )
 {
     gctUINT32_PTR pageTable;
     gctUINT32 index;
-    gctUINT32 mtlb, stlb;
-    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea;
+    gctUINT32 mtlbOffset, stlbOffset;
+    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, PageType, gcvFALSE);
 
     gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
     gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
 
     gcmkASSERT(Mmu->hardware->mmuVersion > 0);
 
-    mtlb   = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+    mtlbOffset = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
 
-    if (mtlb >= area->mappingStart)
+    if (mtlbOffset >= area->mappingStart)
     {
-        stlb   = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+        gctUINT32 stlbShift = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_SHIFT : gcdMMU_STLB_4K_SHIFT;
+        gctUINT32 stlbMask  = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_MASK : gcdMMU_STLB_4K_MASK;
+        gctUINT32 stlbEntryNum = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_ENTRY_NUM : gcdMMU_STLB_4K_ENTRY_NUM;
+
+        stlbOffset = (Address & stlbMask) >> stlbShift;
 
         pageTable = area->stlbLogical;
 
-        index = (mtlb - area->mappingStart)
-            * gcdMMU_STLB_4K_ENTRY_NUM
-            + stlb;
+        index = (mtlbOffset - area->mappingStart) * stlbEntryNum + stlbOffset;
 
         *PageTable = pageTable + index;
     }
@@ -3088,7 +3350,44 @@ gckMMU_GetPageEntry(
     return gcvSTATUS_OK;
 }
 
-/******************************************************************************
-****************************** T E S T   C O D E ******************************
-******************************************************************************/
+gceSTATUS
+gckMMU_GetAreaType(
+    IN gckMMU Mmu,
+    IN gctUINT32 GpuAddress,
+    OUT gceAREA_TYPE *AreaType
+    )
+{
+    gctUINT32 mtlbIndex;
+    gctBOOL flatMapped;
+    gceSTATUS status = gcvSTATUS_OK;
+    gcsADDRESS_AREA_PTR area4K = &Mmu->dynamicArea4K;
+#if gcdENABLE_GPU_1M_PAGE
+    gcsADDRESS_AREA_PTR area1M = &Mmu->dynamicArea1M;
+#endif
+
+    mtlbIndex = _MtlbOffset(GpuAddress);
+
+    gcmkONERROR(gckMMU_IsFlatMapped(Mmu, gcvINVALID_PHYSICAL_ADDRESS, GpuAddress, &flatMapped));
 
+    if (flatMapped)
+    {
+        *AreaType = gcvAREA_TYPE_FLATMAP;
+    }
+#if gcdENABLE_GPU_1M_PAGE
+    else if (mtlbIndex >= area1M->mappingStart && mtlbIndex <= area1M->mappingEnd)
+    {
+        *AreaType = gcvAREA_TYPE_1M;
+    }
+#endif
+    else if (mtlbIndex >= area4K->mappingStart && mtlbIndex <= area4K->mappingEnd)
+    {
+        *AreaType = gcvAREA_TYPE_4K;
+    }
+    else
+    {
+        *AreaType = gcvAREA_TYPE_UNKNOWN;
+    }
+
+OnError:
+    return status;
+}
index 82b66a46ef2b6a883f4e2b54a51d7f5a9459da76..c934268022c4f10ef4fd87311754fb1098ca58b1 100644 (file)
@@ -1006,6 +1006,763 @@ OnError:
     return status;
 }
 
+static gceSTATUS
+_AddToBlockList(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    VidMemBlock->next   = Kernel->vidMemBlock;
+    Kernel->vidMemBlock = VidMemBlock;
+
+    return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_RemoveFromBlockList(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    gckVIDMEM_BLOCK vidMemBlock;
+    gckVIDMEM_BLOCK previous = gcvNULL;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    for (vidMemBlock = Kernel->vidMemBlock; vidMemBlock != gcvNULL; vidMemBlock = vidMemBlock->next)
+    {
+        if (vidMemBlock->addresses[hwType] == VidMemBlock->addresses[hwType])
+        {
+            if (previous)
+            {
+                previous->next = vidMemBlock->next;
+            }
+            else
+            {
+                Kernel->vidMemBlock = vidMemBlock->next;
+            }
+            vidMemBlock->next = gcvNULL;
+
+            break;
+        }
+        previous = vidMemBlock;
+    }
+
+    return gcvSTATUS_OK;
+}
+
+static gckVIDMEM_BLOCK
+_FindFreeBlock(
+    IN gckKERNEL Kernel,
+    IN gctSIZE_T Bytes
+    )
+{
+    gckVIDMEM_BLOCK vidMemBlock;
+
+    for (vidMemBlock = Kernel->vidMemBlock; vidMemBlock != gcvNULL; vidMemBlock = vidMemBlock->next)
+    {
+        if (vidMemBlock->freeBytes >= Bytes)
+        {
+            /* Found the block */
+            break;
+        }
+    }
+
+    return vidMemBlock;
+}
+
+static gceSTATUS
+_SplitVirtualChunk(
+    IN gckOS Os,
+    IN gcuVIDMEM_NODE_PTR Node,
+    IN gctSIZE_T Bytes
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gctPOINTER pointer;
+    gctINT i;
+
+    if ((Bytes <= 0) || (Bytes > Node->VirtualChunk.bytes))
+    {
+        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+    }
+
+    /* Allocate a new gcuVIDMEM_NODE object. */
+    gcmkONERROR(gckOS_Allocate(Os,
+                               gcmSIZEOF(gcuVIDMEM_NODE),
+                               &pointer));
+
+    node = pointer;
+
+    /* Intialize the new gcuVIDMEM_NODE. */
+    node->VirtualChunk.offset = Node->VirtualChunk.offset + Bytes;
+    node->VirtualChunk.bytes  = Node->VirtualChunk.bytes - Bytes;
+    node->VirtualChunk.parent = Node->VirtualChunk.parent;
+    node->VirtualChunk.kernel = Node->VirtualChunk.kernel;
+    node->VirtualChunk.kvaddr = gcvNULL;
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
+    {
+        node->VirtualChunk.lockeds[i] = 0;
+    }
+
+    /* Insert chunk behind specified chunk. */
+    node->VirtualChunk.next  = Node->VirtualChunk.next;
+    node->VirtualChunk.prev  = Node;
+    Node->VirtualChunk.next = node->VirtualChunk.next->VirtualChunk.prev = node;
+
+    /* Insert free chunk behind specified chunk. */
+    node->VirtualChunk.nextFree  = Node->VirtualChunk.nextFree;
+    node->VirtualChunk.prevFree  = Node;
+    Node->VirtualChunk.nextFree = node->VirtualChunk.nextFree->VirtualChunk.prevFree = node;
+
+    /* Adjust size of specified chunk. */
+    Node->VirtualChunk.bytes = Bytes;
+
+OnError:
+    return status;
+}
+
+static gceSTATUS
+_MergeVirtualChunk(
+    IN gckOS Os,
+    IN gcuVIDMEM_NODE_PTR Node
+    )
+{
+    gcuVIDMEM_NODE_PTR node;
+    gceSTATUS status = gcvSTATUS_OK;
+
+    node = Node->VirtualChunk.next;
+
+    if (Node->VirtualChunk.offset + Node->VirtualChunk.bytes != node->VirtualChunk.offset)
+    {
+        /* Corrupted heap. */
+        gcmkASSERT(
+            Node->VirtualChunk.offset + Node->VirtualChunk.bytes == node->VirtualChunk.offset);
+
+        return gcvSTATUS_HEAP_CORRUPTED;
+    }
+
+    /* Merge. */
+    Node->VirtualChunk.bytes += node->VirtualChunk.bytes;
+
+    /* Unlink next node from linked list. */
+    Node->VirtualChunk.next     = node->VirtualChunk.next;
+    Node->VirtualChunk.nextFree = node->VirtualChunk.nextFree;
+
+    Node->VirtualChunk.next->VirtualChunk.prev         =
+    Node->VirtualChunk.nextFree->VirtualChunk.prevFree = Node;
+
+    /* Free the next node. */
+    status = gcmkOS_SAFE_FREE(Os, node);
+    return status;
+}
+
+static gctBOOL
+_IsVidMemBlockFree(
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    return (VidMemBlock->freeBytes == VidMemBlock->bytes);
+}
+
+static gcuVIDMEM_NODE_PTR
+_FindVirtualChunkNode(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock,
+    IN gctSIZE_T Bytes
+    )
+{
+    gcuVIDMEM_NODE_PTR node;
+
+    if (VidMemBlock->node.VirtualChunk.nextFree == gcvNULL)
+    {
+        /* No free chunk left. */
+        return gcvNULL;
+    }
+
+    for (node = VidMemBlock->node.VirtualChunk.nextFree;
+         node->VirtualChunk.bytes != 0;
+         node = node->VirtualChunk.nextFree)
+    {
+        if (node->VirtualChunk.bytes >= Bytes)
+        {
+            /* Got it. */
+            return node;
+        }
+    }
+
+    return gcvNULL;
+}
+
+/*******************************************************************************
+**
+** _ConvertPhysical
+**
+**  Convert CPU physical to GPU address for video node.
+**
+**  INPUT:
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**      gcuVIDMEM_NODE_PTR Node
+**          Pointer to a gcuVIDMEM_NODE union.
+**
+**      gceCORE Core
+**          Id of current GPU.
+**
+**      gctPHYS_ADDR_T PhysicalAddress
+**          CPU physical address
+**
+**  OUTPUT:
+**      gctUINT32 * Address
+**          A pointer hold the GPU address.
+*/
+static gceSTATUS
+_ConvertPhysical(
+    IN gckKERNEL Kernel,
+    IN gceCORE Core,
+    IN gcuVIDMEM_NODE_PTR Node,
+    IN gckVIDMEM_BLOCK VidMemBlock,
+    IN gctPHYS_ADDR_T PhysicalAddress,
+    OUT gctUINT32 * Address
+    )
+{
+    gceSTATUS status;
+    gctUINT64 physical = 0;
+
+    gcmkHEADER_ARG("Node=0x%X", Node);
+
+    if ((Node && !Node->Virtual.contiguous) ||
+        (VidMemBlock && !VidMemBlock->contiguous))
+    {
+        /* non-contiguous, mapping is required. */
+        status = gcvSTATUS_NOT_SUPPORTED;
+        goto OnError;
+    }
+
+    if ((Node && Node->Virtual.secure) ||
+        (VidMemBlock && VidMemBlock->secure))
+    {
+        /* Secure, mapping is forced. */
+        status = gcvSTATUS_NOT_SUPPORTED;
+        goto OnError;
+    }
+
+    /* Convert to GPU physical address. */
+    gckOS_CPUPhysicalToGPUPhysical(Kernel->os, PhysicalAddress, &physical);
+
+
+    if ((physical > gcvMAXUINT32) ||
+        (Node && (physical + Node->Virtual.bytes - 1 > gcvMAXUINT32)) ||
+        (VidMemBlock && (physical + VidMemBlock->bytes - 1 > gcvMAXUINT32)))
+    {
+        /* Above 4G (32bit), mapping is required currently. */
+        status = gcvSTATUS_NOT_SUPPORTED;
+        goto OnError;
+    }
+
+    if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_MMU))
+    {
+        if (physical < Kernel->hardware->baseAddress)
+        {
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+        }
+
+        /* Subtract baseAddress to get a GPU address used for programming. */
+        physical -= Kernel->hardware->baseAddress;
+
+        /* 2G upper is virtual space, better to move to gckHARDWARE section. */
+        if (physical + Node->Virtual.bytes > 0x80000000)
+        {
+            /* End is above 2G, ie virtual space. */
+            status = gcvSTATUS_NOT_SUPPORTED;
+            goto OnError;
+        }
+
+        *Address = (gctUINT32)physical;
+
+        gcmkFOOTER_ARG("*Address=0x%X", *Address);
+        return gcvSTATUS_OK;
+    }
+    else
+    {
+        gctBOOL flatMapped;
+
+        gcmkONERROR(gckMMU_IsFlatMapped(Kernel->mmu, physical, gcvINVALID_ADDRESS, &flatMapped));
+
+        if (!flatMapped)
+        {
+            status = gcvSTATUS_NOT_SUPPORTED;
+            goto OnError;
+        }
+
+        *Address = (gctUINT32)physical;
+
+        gcmkFOOTER_ARG("*Address=0x%X", *Address);
+        return gcvSTATUS_OK;
+    }
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+gckVIDMEM_MapVidMemBlock(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    gceSTATUS status;
+    gckOS os = Kernel->os;
+    gctPHYS_ADDR_T physAddr;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkHEADER_ARG("Kernel=%p VidMemBlock=%p", Kernel, VidMemBlock);
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+    gcmkASSERT(VidMemBlock->pageCount > 0);
+
+    gcmkONERROR(
+        gckOS_GetPhysicalFromHandle(os,
+                                    VidMemBlock->physical,
+                                    0,
+                                    &physAddr));
+
+    status = _ConvertPhysical(Kernel,
+                              Kernel->core,
+                              gcvNULL,
+                              VidMemBlock,
+                              physAddr,
+                              &VidMemBlock->addresses[hwType]);
+    if (gcmIS_ERROR(status))
+    {
+        /* Allocate pages inside the MMU. */
+        gcmkONERROR(
+            gckMMU_AllocatePagesEx(Kernel->mmu,
+                                   VidMemBlock->pageCount,
+                                   VidMemBlock->type,
+                                   gcvPAGE_TYPE_1M,
+                                   VidMemBlock->secure,
+                                   &VidMemBlock->pageTables[hwType],
+                                   &VidMemBlock->addresses[hwType]));
+
+        if (VidMemBlock->onFault != gcvTRUE)
+        {
+            /* Map the pages. */
+            gcmkONERROR(
+                gckOS_Map1MPages(os,
+                                 Kernel->core,
+                                 VidMemBlock->physical,
+                                 VidMemBlock->pageCount,
+                                 VidMemBlock->addresses[hwType],
+                                 VidMemBlock->pageTables[hwType],
+                                 gcvTRUE,
+                                 VidMemBlock->type));
+        }
+
+        gcmkONERROR(gckMMU_Flush(Kernel->mmu, VidMemBlock->type));
+
+        /* Calculate the GPU virtual address. */
+        VidMemBlock->addresses[hwType] |= (gctUINT32) (physAddr & ((1 << 20) - 1));
+    }
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                   "Mapped video memory block 0x%x to 0x%08X",
+                   VidMemBlock,
+                   VidMemBlock->addresses[hwType]);
+
+    return gcvSTATUS_OK;
+
+OnError:
+    if (VidMemBlock->pageTables[hwType] != gcvNULL)
+    {
+        /* Free the pages from the MMU. */
+        gcmkVERIFY_OK(
+            gckMMU_FreePages(Kernel->mmu,
+                             VidMemBlock->secure,
+                             gcvPAGE_TYPE_1M,
+                             VidMemBlock->addresses[hwType],
+                             VidMemBlock->pageTables[hwType],
+                             VidMemBlock->pageCount));
+
+        VidMemBlock->pageTables[hwType] = gcvNULL;
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_UnmapVidMemBlock(
+    IN gckMMU Mmu,
+    IN gceHARDWARE_TYPE HwType,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    gceSTATUS status;
+
+    gcmkHEADER_ARG("Mmu=%p VidMemBlock=%p", Mmu, VidMemBlock);
+
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+
+    if (VidMemBlock->pageTables[HwType] != gcvNULL)
+    {
+        /* Free the pages from the MMU. */
+        gcmkONERROR(
+            gckMMU_FreePages(Mmu,
+                             VidMemBlock->secure,
+                             gcvPAGE_TYPE_1M,
+                             VidMemBlock->addresses[HwType],
+                             VidMemBlock->pageTables[HwType],
+                             VidMemBlock->pageCount));
+
+        VidMemBlock->pageTables[HwType] = gcvNULL;
+    }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+gckVIDMEM_BLOCK_Construct(
+    IN gckKERNEL Kernel,
+    IN gctSIZE_T BlockSize,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    OUT gckVIDMEM_BLOCK * VidMemBlock
+    )
+{
+    gceSTATUS status;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckOS os = Kernel->os;
+    gctPOINTER pointer;
+    gctINT i;
+
+    gcmkHEADER_ARG("Kernel=0x%x BlockSize=%lu Type=%x Flag=%x", Kernel, BlockSize, Type);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_ARGUMENT(BlockSize > 0);
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+
+    /* Allocate an gckVIDMEM_BLOCK object. */
+    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_BLOCK), &pointer));
+
+    vidMemBlock = pointer;
+
+    /* Initialize the gckVIDMEM_BLOCK object. */
+    vidMemBlock->object.type = gcvOBJ_VIDMEM_BLOCK;
+    vidMemBlock->os          = os;
+    vidMemBlock->bytes       = BlockSize;
+    vidMemBlock->freeBytes   = BlockSize;
+    /* 1M page count. */
+    vidMemBlock->pageCount   = (gctUINT32)(BlockSize >> 20);
+    vidMemBlock->type        = Type;
+    vidMemBlock->contiguous  = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+    vidMemBlock->secure      = (Flag & gcvALLOC_FLAG_SECURITY) != 0;
+    vidMemBlock->onFault     = (Flag & gcvALLOC_FLAG_ALLOC_ON_FAULT) != 0;
+    vidMemBlock->mutex       = gcvNULL;
+    vidMemBlock->physical    = gcvNULL;
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
+    {
+        vidMemBlock->pageTables[i] = gcvNULL;
+    }
+
+    /* Allocate the mutex. */
+    gcmkONERROR(gckOS_CreateMutex(os, &vidMemBlock->mutex));
+
+    /* Allocate one gcuVIDMEM_NODE union. */
+    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
+
+    node = pointer;
+
+    if (!vidMemBlock->contiguous)
+    {
+        Flag |= gcvALLOC_FLAG_1M_PAGES;
+    }
+
+    /* Alloc 1M page size aligned memory block. */
+    gcmkONERROR(
+        gckOS_AllocatePagedMemory(os,
+                                  Flag,
+                                  &BlockSize,
+                                  &vidMemBlock->gid,
+                                  &vidMemBlock->physical));
+
+    /* Map current hardware mmu table with 1M pages for this video memory block. */
+    gcmkONERROR(gckVIDMEM_MapVidMemBlock(Kernel, vidMemBlock));
+
+    /* Initialize gcuVIDMEM_NODE union for virtual memory. */
+    node->VirtualChunk.kernel     = Kernel;
+    node->VirtualChunk.offset     = 0;
+    node->VirtualChunk.bytes      = BlockSize;
+    node->VirtualChunk.kvaddr     = gcvNULL;
+    node->VirtualChunk.logical    = gcvNULL;
+    node->VirtualChunk.parent     = vidMemBlock;
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
+    {
+        node->VirtualChunk.lockeds[i] = 0;
+    }
+
+    /* Initialize the virtual chunk linked-list. */
+    node->VirtualChunk.next     =
+    node->VirtualChunk.prev     =
+    node->VirtualChunk.nextFree =
+    node->VirtualChunk.prevFree = &vidMemBlock->node;
+
+    vidMemBlock->node.VirtualChunk.next =
+    vidMemBlock->node.VirtualChunk.prev =
+    vidMemBlock->node.VirtualChunk.nextFree =
+    vidMemBlock->node.VirtualChunk.prevFree = node;
+
+    vidMemBlock->node.VirtualChunk.bytes = 0;
+
+    *VidMemBlock = vidMemBlock;
+
+    gcmkFOOTER_ARG("*VidMemBlock=0x%x", *VidMemBlock);
+
+    return gcvSTATUS_OK;
+
+OnError:
+    if (vidMemBlock != gcvNULL)
+    {
+        if (vidMemBlock->mutex)
+        {
+            gcmkVERIFY_OK(gckOS_DeleteMutex(os, vidMemBlock->mutex));
+        }
+
+        if (vidMemBlock->physical)
+        {
+            gcmkVERIFY_OK(gckOS_FreePagedMemory(os,
+                                                vidMemBlock->physical,
+                                                vidMemBlock->bytes));
+        }
+
+        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, vidMemBlock));
+    }
+
+    if (node != gcvNULL)
+    {
+        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+gckVIDMEM_BLOCK_Destroy(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    gckDEVICE device = Kernel->device;
+    gctINT i;
+
+    gcmkHEADER_ARG("Kernel=%p VidMemBlock=%p", Kernel, VidMemBlock);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+
+    if (VidMemBlock->physical)
+    {
+        gcmkVERIFY_OK(gckOS_FreePagedMemory(Kernel->os,
+                                            VidMemBlock->physical,
+                                            VidMemBlock->bytes));
+    }
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
+    {
+        if (VidMemBlock->pageTables[i])
+        {
+            gcmkVERIFY_OK(_UnmapVidMemBlock(device->mmus[i], i, VidMemBlock));
+        }
+    }
+
+    /* Free the mutex. */
+    gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, VidMemBlock->mutex));
+
+    /* Free the virtual chunk. */
+    gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, VidMemBlock->node.VirtualChunk.next));
+
+    /* Free the video memory block. */
+    gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, VidMemBlock));
+
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_AllocateVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK  VidMemBlock,
+    IN gceVIDMEM_TYPE Type,
+    INOUT gctSIZE_T *Bytes,
+    OUT gcuVIDMEM_NODE_PTR *Node
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gctBOOL acquired = gcvFALSE;
+    gcuVIDMEM_NODE_PTR node;
+    gctSIZE_T bytes;
+
+    gcmkHEADER_ARG("Kernel=%p VidMemBlock=%p Type=%x Bytes=%zx",
+        Kernel, VidMemBlock, Type, *Bytes);
+
+    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+    gcmkVERIFY_ARGUMENT(Bytes > 0);
+    gcmkVERIFY_ARGUMENT(Type < gcvVIDMEM_TYPE_COUNT);
+
+    gcmkONERROR(gckOS_AcquireMutex(Kernel->os, VidMemBlock->mutex, gcvINFINITE));
+
+    acquired = gcvTRUE;
+
+    bytes = gcmALIGN(*Bytes, 4096);
+
+    if (bytes > VidMemBlock->freeBytes)
+    {
+        /* No enough memory. */
+        status = gcvSTATUS_OUT_OF_MEMORY;
+        goto OnError;
+    }
+
+    node = _FindVirtualChunkNode(Kernel, VidMemBlock, bytes);
+    if (node == gcvNULL)
+    {
+        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+    }
+
+    if (node->VirtualChunk.bytes > bytes)
+    {
+        /* Split the chunk. */
+        _SplitVirtualChunk(Kernel->os, node, bytes);
+    }
+
+    /* Remove the chunk from the free list. */
+    node->VirtualChunk.prevFree->VirtualChunk.nextFree = node->VirtualChunk.nextFree;
+    node->VirtualChunk.nextFree->VirtualChunk.prevFree = node->VirtualChunk.prevFree;
+    node->VirtualChunk.nextFree = node->VirtualChunk.prevFree = gcvNULL;
+
+    /* Fill in the information. */
+    node->VirtualChunk.parent = VidMemBlock;
+
+    VidMemBlock->freeBytes -= node->VirtualChunk.bytes;
+
+    *Bytes = bytes;
+    *Node  = node;
+
+OnError:
+    if (acquired)
+    {
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, VidMemBlock->mutex));
+    }
+
+    return status;
+}
+
+static gceSTATUS
+gckVIDMEM_AllocateVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN gctSIZE_T Bytes,
+    OUT gcuVIDMEM_NODE_PTR * Node
+    )
+{
+    gckOS os;
+    gceSTATUS status;
+    gcuVIDMEM_NODE_PTR node;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
+    gctSIZE_T blockSize;
+    gctBOOL acquired = gcvFALSE;
+
+    gcmkHEADER_ARG("Kernel=0x%x Flag=%x Bytes=%lu", Kernel, Flag, Bytes);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+    gcmkVERIFY_ARGUMENT(Bytes > 0);
+    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+
+    /* Extract the gckOS object pointer. */
+    os = Kernel->os;
+    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+    /* Acquire the vidMem block mutex */
+    gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vidMemBlockMutex, gcvINFINITE));
+    acquired = gcvTRUE;
+
+    /* Find the free vidmem block. */
+    vidMemBlock = _FindFreeBlock(Kernel, Bytes);
+    if (!vidMemBlock)
+    {
+        /* Not found, construct new block. */
+        blockSize = gcmALIGN(Bytes, gcd1M_PAGE_SIZE);
+
+        gcmkONERROR(
+            gckVIDMEM_BLOCK_Construct(Kernel,
+                                      blockSize,
+                                      Type,
+                                      Flag,
+                                      &vidMemBlock));
+
+        gcmkONERROR(_AddToBlockList(Kernel, vidMemBlock));
+    }
+
+    /* Allocate virtual chunk node in the found block. */
+    gcmkONERROR(
+        _AllocateVirtualChunk(Kernel,
+                              vidMemBlock,
+                              Type,
+                              &Bytes,
+                              &node));
+
+    /* Return pointer to the gcuVIDMEM_NODE union. */
+    *Node = node;
+
+    /* Release the vidMem block mutex. */
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidMemBlockMutex));
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                   "Created virtual node 0x%x for %u bytes @ 0x%x",
+                   node, Bytes, node->Virtual.physical);
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Node=0x%x", *Node);
+    return gcvSTATUS_OK;
+
+OnError:
+    if (acquired)
+    {
+        /* Release the vidMem block mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidMemBlockMutex));
+    }
+
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
 /*******************************************************************************
 **
 **  gckVIDMEM_Free
@@ -1033,8 +1790,11 @@ gckVIDMEM_Free(
     gceSTATUS status;
     gckKERNEL kernel = gcvNULL;
     gckVIDMEM memory = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
     gcuVIDMEM_NODE_PTR node;
     gctBOOL mutexAcquired = gcvFALSE;
+    gctBOOL vbMutexAcquired = gcvFALSE;
+    gctBOOL vbListMutexAcquired = gcvFALSE;
 
     gcmkHEADER_ARG("Node=0x%x", Node);
 
@@ -1047,6 +1807,8 @@ gckVIDMEM_Free(
         gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
     }
 
+    vidMemBlock = Node->VirtualChunk.parent;
+
     /**************************** Video Memory ********************************/
 
     if (Node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
@@ -1109,6 +1871,11 @@ gckVIDMEM_Free(
                  node != gcvNULL && node->VidMem.nextFree == gcvNULL;
                  node = node->VidMem.next) ;
 
+            if (node == gcvNULL)
+            {
+                gcmkONERROR(gcvSTATUS_INVALID_DATA);
+            }
+
             /* Insert this node in the free list. */
             Node->VidMem.nextFree = node;
             Node->VidMem.prevFree = node->VidMem.prevFree;
@@ -1150,6 +1917,97 @@ gckVIDMEM_Free(
         gcmkFOOTER_NO();
         return gcvSTATUS_OK;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        gckOS os = vidMemBlock->os;
+
+        gcmkONERROR(gckOS_AcquireMutex(os, vidMemBlock->mutex, gcvINFINITE));
+        vbMutexAcquired = gcvTRUE;
+        kernel = Node->VirtualChunk.kernel;
+
+        if (Node->VirtualChunk.kvaddr)
+        {
+            gcmkONERROR(
+                gckOS_DestroyKernelMapping(kernel->os,
+                                           vidMemBlock->physical,
+                                           Node->VirtualChunk.kvaddr));
+
+            Node->VirtualChunk.kvaddr = gcvNULL;
+        }
+
+        /* Handle the free chunk in the linked-list */
+        {
+            /* Check if chunk is in free list. */
+            if (Node->VirtualChunk.nextFree)
+            {
+                /* Chunk is already freed. */
+                gcmkONERROR(gcvSTATUS_INVALID_DATA);
+            }
+
+            vidMemBlock->freeBytes += Node->VirtualChunk.bytes;
+
+            /* Find the next free chunk. */
+            for (node = Node->VirtualChunk.next;
+                 node != gcvNULL && node->VirtualChunk.nextFree == gcvNULL;
+                 node = node->VirtualChunk.next);
+
+            if (node == gcvNULL)
+            {
+                gcmkONERROR(gcvSTATUS_INVALID_DATA);
+            }
+
+            /* Insert this chunk in the free list. */
+            Node->VirtualChunk.nextFree = node;
+            Node->VirtualChunk.prevFree = node->VirtualChunk.prevFree;
+
+            Node->VirtualChunk.prevFree->VirtualChunk.nextFree =
+            node->VirtualChunk.prevFree = Node;
+
+            /* Is the next chunk a free chunk. */
+            if ((Node->VirtualChunk.next == Node->VirtualChunk.nextFree)
+            &&  (Node->VirtualChunk.next->VirtualChunk.bytes != 0)
+            )
+            {
+                /* Merge this chunk with the next chunk. */
+                gcmkONERROR(_MergeVirtualChunk(os, node = Node));
+                gcmkASSERT(node->VirtualChunk.nextFree != node);
+                gcmkASSERT(node->VirtualChunk.prevFree != node);
+            }
+
+            /* Is the previous chunk a free chunk. */
+            if ((Node->VirtualChunk.prev == Node->VirtualChunk.prevFree)
+            &&  (Node->VirtualChunk.prev->VirtualChunk.bytes != 0)
+            )
+            {
+                /* Merge this chunk with the previous chunk. */
+                gcmkONERROR(_MergeVirtualChunk(os, node = Node->VirtualChunk.prev));
+                gcmkASSERT(node->VirtualChunk.nextFree != node);
+                gcmkASSERT(node->VirtualChunk.prevFree != node);
+            }
+        }
+
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, vidMemBlock->mutex));
+
+        /* Acquire the vidMem block mutex */
+        gcmkONERROR(gckOS_AcquireMutex(os, kernel->vidMemBlockMutex, gcvINFINITE));
+        vbListMutexAcquired = gcvTRUE;
+
+        /* Only free the vidmem block when all the chunks are freed. */
+        if (_IsVidMemBlockFree(vidMemBlock))
+        {
+            gcmkONERROR(_RemoveFromBlockList(kernel, vidMemBlock));
+
+            gcmkONERROR(gckVIDMEM_BLOCK_Destroy(kernel, vidMemBlock));
+        }
+
+        /* Release the vidMem block mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->vidMemBlockMutex));
+
+        /* Success. */
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
 
     /*************************** Virtual Memory *******************************/
 
@@ -1180,125 +2038,29 @@ gckVIDMEM_Free(
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
-OnError:
-    if (mutexAcquired)
-    {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(
-            memory->os, memory->mutex
-            ));
-    }
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-** _ConvertPhysical
-**
-**  Convert CPU physical to GPU address for video node.
-**
-**  INPUT:
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gcuVIDMEM_NODE_PTR Node
-**          Pointer to a gcuVIDMEM_NODE union.
-**
-**      gceCORE Core
-**          Id of current GPU.
-**
-**      gctPHYS_ADDR_T PhysicalAddress
-**          CPU physical address
-**
-**  OUTPUT:
-**      gctUINT32 * Address
-**          A pointer hold the GPU address.
-*/
-static gceSTATUS
-_ConvertPhysical(
-    IN gckKERNEL Kernel,
-    IN gceCORE Core,
-    IN gcuVIDMEM_NODE_PTR Node,
-    IN gctPHYS_ADDR_T PhysicalAddress,
-    OUT gctUINT32 * Address
-    )
-{
-    gceSTATUS status;
-    gctUINT64 physical = 0;
-
-    gcmkHEADER_ARG("Node=0x%X", Node);
-
-    if (!Node->Virtual.contiguous)
-    {
-        /* non-contiguous, mapping is required. */
-        status = gcvSTATUS_NOT_SUPPORTED;
-        goto OnError;
-    }
-
-    if (Node->Virtual.secure)
-    {
-        /* Secure, mapping is forced. */
-        status = gcvSTATUS_NOT_SUPPORTED;
-        goto OnError;
-    }
-
-    /* Convert to GPU physical address. */
-    gckOS_CPUPhysicalToGPUPhysical(Kernel->os, PhysicalAddress, &physical);
-
-
-    if ((physical > gcvMAXUINT32) ||
-        (physical + Node->Virtual.bytes - 1 > gcvMAXUINT32))
-    {
-        /* Above 4G (32bit), mapping is required currently. */
-        status = gcvSTATUS_NOT_SUPPORTED;
-        goto OnError;
-    }
-
-    if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_MMU))
-    {
-        if (physical < Kernel->hardware->baseAddress)
-        {
-            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-        }
-
-        /* Subtract baseAddress to get a GPU address used for programming. */
-        physical -= Kernel->hardware->baseAddress;
-
-        /* 2G upper is virtual space, better to move to gckHARDWARE section. */
-        if (physical + Node->Virtual.bytes > 0x80000000)
-        {
-            /* End is above 2G, ie virtual space. */
-            status = gcvSTATUS_NOT_SUPPORTED;
-            goto OnError;
-        }
-
-        *Address = (gctUINT32)physical;
-
-        gcmkFOOTER_ARG("*Address=0x%X", *Address);
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        gctBOOL flatMapped;
-
-        gcmkONERROR(gckMMU_IsFlatMapped(Kernel->mmu, (gctUINT32)physical, &flatMapped));
-
-        if (!flatMapped)
-        {
-            status = gcvSTATUS_NOT_SUPPORTED;
-            goto OnError;
-        }
-
-        *Address = (gctUINT32)physical;
+OnError:
+    if (mutexAcquired)
+    {
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(
+            memory->os, memory->mutex
+            ));
+    }
 
-        gcmkFOOTER_ARG("*Address=0x%X", *Address);
-        return gcvSTATUS_OK;
+    if (vbMutexAcquired)
+    {
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(
+            vidMemBlock->os, vidMemBlock->mutex
+            ));
     }
 
-OnError:
+    if (vbListMutexAcquired)
+    {
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(
+            vidMemBlock->os, Kernel->vidMemBlockMutex));
+    }
+
+    /* Return the status. */
     gcmkFOOTER();
     return status;
 }
@@ -1354,9 +2116,12 @@ gckVIDMEM_Lock(
         case gcvPOOL_LOCAL_INTERNAL:
             address = Kernel->internalBaseAddress + offset;
             break;
-        case gcvPOOL_SRAM:
+        case gcvPOOL_INTERNAL_SRAM:
             address = Kernel->sRAMBaseAddresses[Kernel->sRAMIndex] + offset;
             break;
+        case gcvPOOL_EXTERNAL_SRAM:
+            address = Kernel->extSRAMBaseAddresses[Kernel->extSRAMIndex] + offset;
+            break;
         default:
             gcmkASSERT(Node->VidMem.pool == gcvPOOL_SYSTEM);
         case gcvPOOL_SYSTEM:
@@ -1418,6 +2183,7 @@ gckVIDMEM_LockVirtual(
             Kernel,
             Kernel->core,
             Node,
+            gcvNULL,
             physicalAddress,
             &Node->Virtual.addresses[hwType]
             );
@@ -1457,6 +2223,7 @@ gckVIDMEM_LockVirtual(
                     gckMMU_AllocatePagesEx(Kernel->mmu,
                                            Node->Virtual.pageCount,
                                            Node->Virtual.type,
+                                           gcvPAGE_TYPE_4K,
                                            Node->Virtual.secure,
                                            &Node->Virtual.pageTables[hwType],
                                            &Node->Virtual.addresses[hwType]));
@@ -1478,6 +2245,10 @@ gckVIDMEM_LockVirtual(
                 else
 #endif
                 {
+                    gcmkDUMP(os, "#[mmu: dynamic mapping: address=0x%08X pageCount=%lu]",
+                             Node->Virtual.addresses[hwType],
+                             (unsigned long)Node->Virtual.pageCount);
+
                     /* Map the pages. */
                     gcmkONERROR(gckOS_MapPagesEx(os,
                         Kernel->core,
@@ -1521,6 +2292,7 @@ OnError:
                 gcmkVERIFY_OK(
                     gckMMU_FreePages(Kernel->mmu,
                                      Node->Virtual.secure,
+                                     gcvPAGE_TYPE_4K,
                                      Node->Virtual.addresses[hwType],
                                      Node->Virtual.pageTables[hwType],
                                      Node->Virtual.pageCount));
@@ -1536,6 +2308,50 @@ OnError:
     return status;
 }
 
+static gceSTATUS
+gckVIDMEM_LockVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gcuVIDMEM_NODE_PTR Node,
+    OUT gctUINT32 * Address
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gckVIDMEM_BLOCK vidMemBlock = Node->VirtualChunk.parent;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkHEADER_ARG("Kernel=%p Node=%p", Kernel, Node);
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    gcmkASSERT(vidMemBlock != gcvNULL);
+
+    /* Increment the lock count. */
+    if (Node->VirtualChunk.lockeds[hwType]++ == 0)
+    {
+        if (!vidMemBlock->pageTables[hwType])
+        {
+            /* Map current hardware mmu table with 1M pages for this video memory block. */
+            gcmkONERROR(gckVIDMEM_MapVidMemBlock(Kernel, vidMemBlock));
+        }
+
+        Node->VirtualChunk.addresses[hwType] = vidMemBlock->addresses[hwType]
+                                             + (gctUINT32)Node->VirtualChunk.offset;
+    }
+
+    /* Return hardware address. */
+    *Address = Node->VirtualChunk.addresses[hwType];
+
+    gcmkFOOTER_ARG("*Address=0x%08X", *Address);
+
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
 /*******************************************************************************
 **
 **  gckVIDMEM_Unlock
@@ -1662,6 +2478,7 @@ gckVIDMEM_UnlockVirtual(
                     gcmkONERROR(
                         gckMMU_FreePages(Kernel->mmu,
                                          Node->Virtual.secure,
+                                         gcvPAGE_TYPE_4K,
                                          address,
                                          Node->Virtual.pageTables[hwType],
                                          Node->Virtual.pageCount));
@@ -1693,7 +2510,56 @@ OnError:
     return status;
 }
 
+static gceSTATUS
+gckVIDMEM_UnlockVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gcuVIDMEM_NODE_PTR Node,
+    IN OUT gctBOOL * Asynchroneous
+    )
+{
+    gceSTATUS status;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkHEADER_ARG("Node=0x%x *Asynchroneous=%d",
+                   Node, gcmOPT_VALUE(Asynchroneous));
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    if (Asynchroneous != gcvNULL)
+    {
+        /* Schedule an event to sync with GPU. */
+        *Asynchroneous = gcvTRUE;
+    }
+    else
+    {
+        if (Node->VirtualChunk.lockeds[hwType] == 0)
+        {
+            /* The surface was not locked. */
+            gcmkONERROR(gcvSTATUS_MEMORY_UNLOCKED);
+        }
+
+        /* Unmap and free pages when video memory free. */
+
+        /* Decrement the lock count. */
+        --Node->VirtualChunk.lockeds[hwType];
+    }
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                  "Unlocked node %p (%d)",
+                  Node,
+                  Node->VirtualChunk.lockeds[hwType]);
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
+    return gcvSTATUS_OK;
 
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
 /*******************************************************************************
 **
 **  gckVIDMEM_HANDLE_Allocate
@@ -2002,6 +2868,12 @@ gckVIDMEM_NODE_Construct(
 
     node = pointer;
 
+    node->metadata.magic = VIV_VIDMEM_METADATA_MAGIC;
+    node->metadata.ts_fd = -1;
+#ifdef gcdANDROID
+    node->metadata.ts_address = 0;
+#endif
+
     node->node = VideoNode;
     node->kernel = Kernel;
     node->type = Type;
@@ -2159,6 +3031,49 @@ OnError:
     return status;
 }
 
+gceSTATUS
+gckVIDMEM_NODE_AllocateVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
+    )
+{
+    gceSTATUS status;
+    gctSIZE_T bytes = *Bytes;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+
+    gcmkHEADER_ARG("Kernel=%p Pool=%d Type=%d Flag=%x *Bytes=%u",
+                   Kernel, Pool, Type, Flag, bytes);
+
+    gcmkONERROR(
+        gckVIDMEM_AllocateVirtualChunk(Kernel, Type, Flag, bytes, &node));
+
+    bytes = node->VirtualChunk.bytes;
+
+    /* Construct a node. */
+    gcmkONERROR(
+        gckVIDMEM_NODE_Construct(Kernel, node, Type, Pool, &nodeObject));
+
+    *Bytes = bytes;
+    *NodeObject = nodeObject;
+
+    gcmkFOOTER_ARG("*Bytes=%u *NodeObject=%p", bytes, nodeObject);
+    return gcvSTATUS_OK;
+
+OnError:
+    if (node)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node));
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
 gceSTATUS
 gckVIDMEM_NODE_Reference(
     IN gckKERNEL Kernel,
@@ -2270,6 +3185,7 @@ gckVIDMEM_NODE_Lock(
     gckOS os = Kernel->os;
     gctBOOL acquired = gcvFALSE;
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
     gcmkHEADER_ARG("NodeObject=%p", NodeObject);
 
@@ -2281,6 +3197,10 @@ gckVIDMEM_NODE_Lock(
     {
         gcmkONERROR(gckVIDMEM_Lock(Kernel, node, Address));
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        gcmkONERROR(gckVIDMEM_LockVirtualChunk(Kernel, node, Address));
+    }
     else
     {
         gcmkONERROR(gckVIDMEM_LockVirtual(Kernel, node, Address));
@@ -2315,6 +3235,7 @@ gckVIDMEM_NODE_Unlock(
     gckOS os = Kernel->os;
     gctBOOL acquired = gcvFALSE;
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
     gcmkHEADER_ARG("NodeObject=%p Asynchroneous=%p", NodeObject, Asynchroneous);
 
@@ -2326,6 +3247,10 @@ gckVIDMEM_NODE_Unlock(
     {
         gcmkONERROR(gckVIDMEM_Unlock(Kernel, node, Asynchroneous));
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        gcmkONERROR(gckVIDMEM_UnlockVirtualChunk(Kernel, node, Asynchroneous));
+    }
     else
     {
         gcmkONERROR(gckVIDMEM_UnlockVirtual(Kernel, node, Asynchroneous));
@@ -2359,6 +3284,7 @@ gckVIDMEM_NODE_CleanCache(
 {
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
     gctPHYS_ADDR physHandle = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gceSTATUS status;
 
     gcmkHEADER_ARG("Kernel=%p NodeObject=%d Offset=0x%llx Logical=%p Bytes=0x%llx",
@@ -2372,8 +3298,14 @@ gckVIDMEM_NODE_CleanCache(
         gcmkFOOTER_NO();
         return gcvSTATUS_OK;
     }
-
-    physHandle = node->Virtual.physical;
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physHandle = vidMemBlock->physical;
+    }
+    else
+    {
+        physHandle = node->Virtual.physical;
+    }
 
     gcmkONERROR(gckOS_CacheFlush(
         Kernel->os,
@@ -2403,6 +3335,7 @@ gckVIDMEM_NODE_InvalidateCache(
 {
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
     gctPHYS_ADDR physHandle = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gceSTATUS status;
 
     gcmkHEADER_ARG("Kernel=%p NodeObject=%d Offset=0x%llx Logical=%p Bytes=0x%llx",
@@ -2414,8 +3347,14 @@ gckVIDMEM_NODE_InvalidateCache(
         gcmkFOOTER_NO();
         return gcvSTATUS_OK;
     }
-
-    physHandle = node->Virtual.physical;
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physHandle = vidMemBlock->physical;
+    }
+    else
+    {
+        physHandle = node->Virtual.physical;
+    }
 
     gcmkONERROR(gckOS_CacheInvalidate(
         Kernel->os,
@@ -2442,24 +3381,32 @@ gckVIDMEM_NODE_GetLockCount(
     )
 {
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+    gctINT32 lockCount = 0;
+    gctINT i = 0;
 
     if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
-        *LockCount = node->VidMem.locked;
+        lockCount = node->VidMem.locked;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        for (; i < gcvHARDWARE_NUM_TYPES; i++)
+        {
+            lockCount += node->VirtualChunk.lockeds[i];
+        }
     }
     else
     {
-        gctUINT i;
-        gctINT32 lockCount = 0;
 
-        for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
+        for (; i < gcvHARDWARE_NUM_TYPES; i++)
         {
             lockCount += node->Virtual.lockeds[i];
         }
-
-        *LockCount = lockCount;
     }
 
+    *LockCount = lockCount;
+
     return gcvSTATUS_OK;
 }
 
@@ -2476,6 +3423,7 @@ gckVIDMEM_NODE_LockCPU(
     gckOS os = Kernel->os;
     gctBOOL acquired = gcvFALSE;
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gctPOINTER logical = gcvNULL;
 
     gcmkHEADER_ARG("NodeObject=%p", NodeObject);
@@ -2533,6 +3481,38 @@ gckVIDMEM_NODE_LockCPU(
             logical = node->VidMem.kvaddr;
         }
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        if (FromUser)
+        {
+            /* Lock the entire vidmem block. */
+            gcmkONERROR(
+                gckOS_LockPages(os,
+                                vidMemBlock->physical,
+                                vidMemBlock->bytes,
+                                Cacheable,
+                                &logical));
+
+            /* Get the logical with offset in block. */
+            logical = (uint8_t *)logical + node->VirtualChunk.offset;
+            node->VirtualChunk.logical = logical;
+        }
+        else
+        {
+            /* Map once and will cancel map when free. */
+            if (!node->VirtualChunk.kvaddr)
+            {
+                gcmkONERROR(
+                    gckOS_CreateKernelMapping(os,
+                                              vidMemBlock->physical,
+                                              node->VirtualChunk.offset,
+                                              node->VirtualChunk.bytes,
+                                              &node->VirtualChunk.kvaddr));
+            }
+
+            logical = node->VirtualChunk.kvaddr;
+        }
+    }
     else
     {
         if (FromUser)
@@ -2594,6 +3574,7 @@ gckVIDMEM_NODE_UnlockCPU(
     gckOS os = Kernel->os;
     gctBOOL acquired = gcvFALSE;
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
     gcmkHEADER_ARG("NodeObject=%p", NodeObject);
 
@@ -2624,6 +3605,21 @@ gckVIDMEM_NODE_UnlockCPU(
              */
         }
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        if (FromUser)
+        {
+            gcmkONERROR(
+                gckOS_UnlockPages(os,
+                                  vidMemBlock->physical,
+                                  vidMemBlock->bytes,
+                                  node->VirtualChunk.logical));
+        }
+        else
+        {
+            /* Nothing to do. */
+        }
+    }
     else
     {
         if (FromUser)
@@ -2680,6 +3676,7 @@ gckVIDMEM_NODE_GetPhysical(
     gceSTATUS status;
     gckOS os = Kernel->os;
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
     gcmkHEADER_ARG("NodeObject=%p", NodeObject);
 
@@ -2695,6 +3692,20 @@ gckVIDMEM_NODE_GetPhysical(
                          + node->VidMem.offset
                          + Offset;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        if (Offset >= node->VirtualChunk.bytes)
+        {
+            /* Exceeds node size. */
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+        }
+
+        gcmkONERROR(
+            gckOS_GetPhysicalFromHandle(os,
+                                        vidMemBlock->physical,
+                                        (gctUINT32)node->VirtualChunk.offset + Offset,
+                                        PhysicalAddress));
+    }
     else
     {
         if (Offset >= node->Virtual.bytes)
@@ -2726,11 +3737,16 @@ gckVIDMEM_NODE_GetGid(
     )
 {
     gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
     if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
         *Gid = 0;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        *Gid = vidMemBlock->gid;
+    }
     else
     {
         *Gid = node->Virtual.gid;
@@ -2746,11 +3762,21 @@ gckVIDMEM_NODE_GetSize(
     OUT gctSIZE_T * Size
     )
 {
-    gcuVIDMEM_NODE_PTR node;
-    node = NodeObject->node;
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
-    *Size = (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
-          ? node->VidMem.bytes : node->Virtual.bytes;
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        *Size = node->VidMem.bytes;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        *Size = node->VirtualChunk.bytes;
+    }
+    else
+    {
+        *Size = node->Virtual.bytes;
+    }
 
     return gcvSTATUS_OK;
 }
@@ -2801,6 +3827,7 @@ static struct sg_table *_dmabuf_map(struct dma_buf_attachment *attachment,
     do
     {
         gcuVIDMEM_NODE_PTR node = nodeObject->node;
+        gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
         gctPHYS_ADDR physical = gcvNULL;
         gctSIZE_T offset = 0;
         gctSIZE_T bytes = 0;
@@ -2811,6 +3838,12 @@ static struct sg_table *_dmabuf_map(struct dma_buf_attachment *attachment,
             offset = node->VidMem.offset;
             bytes = node->VidMem.bytes;
         }
+        else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+        {
+            physical = vidMemBlock->physical;
+            offset = node->VirtualChunk.offset;
+            bytes = node->VirtualChunk.bytes;
+        }
         else
         {
             physical = node->Virtual.physical;
@@ -2847,6 +3880,7 @@ static int _dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
 {
     gckVIDMEM_NODE nodeObject = dmabuf->priv;
     gcuVIDMEM_NODE_PTR node = nodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gctPHYS_ADDR physical = gcvNULL;
     gctSIZE_T skipPages = vma->vm_pgoff;
     gctSIZE_T numPages = PAGE_ALIGN(vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
@@ -2857,6 +3891,11 @@ static int _dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
         physical = node->VidMem.parent->physical;
         skipPages += (node->VidMem.offset >> PAGE_SHIFT);
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physical  = vidMemBlock->physical;
+        skipPages += (node->VirtualChunk.offset >> PAGE_SHIFT);
+    }
     else
     {
         physical = node->Virtual.physical;
@@ -2879,6 +3918,7 @@ static void *_dmabuf_kmap(struct dma_buf *dmabuf, unsigned long offset)
 {
     gckVIDMEM_NODE nodeObject = dmabuf->priv;
     gcuVIDMEM_NODE_PTR node = nodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gctINT8_PTR kvaddr = gcvNULL;
     gctPHYS_ADDR physical = gcvNULL;
     gctSIZE_T bytes = 0;
@@ -2890,6 +3930,12 @@ static void *_dmabuf_kmap(struct dma_buf *dmabuf, unsigned long offset)
         offset += node->VidMem.offset;
         bytes = node->VidMem.bytes;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physical = vidMemBlock->physical;
+        offset += node->VirtualChunk.offset;
+        bytes = node->VirtualChunk.bytes;
+    }
     else
     {
         physical = node->Virtual.physical;
@@ -2909,6 +3955,7 @@ static void _dmabuf_kunmap(struct dma_buf *dmabuf, unsigned long offset, void *p
 {
     gckVIDMEM_NODE nodeObject = dmabuf->priv;
     gcuVIDMEM_NODE_PTR node = nodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gctINT8_PTR kvaddr = (gctINT8_PTR)ptr - (offset << PAGE_SHIFT);
     gctPHYS_ADDR physical = gcvNULL;
 
@@ -2917,6 +3964,11 @@ static void _dmabuf_kunmap(struct dma_buf *dmabuf, unsigned long offset, void *p
         physical = node->VidMem.parent->physical;
         kvaddr -= node->VidMem.offset;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physical = vidMemBlock->physical;
+        kvaddr -= node->VirtualChunk.offset;
+    }
     else
     {
         physical = node->Virtual.physical;
@@ -2932,7 +3984,10 @@ static struct dma_buf_ops _dmabuf_ops =
     .unmap_dma_buf = _dmabuf_unmap,
     .mmap = _dmabuf_mmap,
     .release = _dmabuf_release,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)
+    .map = _dmabuf_kmap,
+    .unmap = _dmabuf_kunmap,
+#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
     .map_atomic = _dmabuf_kmap,
     .unmap_atomic = _dmabuf_kunmap,
     .map = _dmabuf_kmap,
@@ -2967,11 +4022,19 @@ gckVIDMEM_NODE_Export(
         gctSIZE_T bytes = 0;
         gctPHYS_ADDR physical = gcvNULL;
         gcuVIDMEM_NODE_PTR node = NodeObject->node;
+        gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
         if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
         {
             physical = node->VidMem.parent->physical;
             bytes = node->VidMem.bytes;
+            /* Align export size. when allocate memory from VIDMEM, the actual node size may not same with aligned size. */
+            bytes = bytes & ~(PAGE_SIZE - 1);
+        }
+        else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+        {
+            physical = vidMemBlock->physical;
+            bytes = node->VirtualChunk.bytes;
         }
         else
         {
@@ -3140,7 +4203,6 @@ OnError:
     return status;
 }
 
-
 typedef struct _gcsVIDMEM_NODE_FDPRIVATE
 {
     gcsFDPRIVATE   base;
@@ -3251,26 +4313,20 @@ gckVIDMEM_NODE_WrapUserMemory(
         {
             /* Import dma buf handle. */
             dmabuf = dma_buf_get(fd);
-            if (IS_ERR(dmabuf))
-            {
-                gcmkPRINT("Wrap user memory: invalid dmabuf fd from user.\n");
 
-                gcmkFOOTER();
-                return gcvSTATUS_INVALID_ARGUMENT;
-            }
+            if (IS_ERR(dmabuf))
+                return PTR_ERR(dmabuf);
 
             Desc->handle = -1;
             Desc->dmabuf = gcmPTR_TO_UINT64(dmabuf);
 
             dma_buf_put(dmabuf);
         }
-        else if (fd == -1)
+        else
         {
-            /* It is called by our kernel drm driver. */
-
-            if (IS_ERR(gcmUINT64_TO_PTR(Desc->dmabuf)))
+            if (!Desc->dmabuf)
             {
-                gcmkPRINT("Wrap memory: invalid dmabuf from kernel.\n");
+                gcmkPRINT("Wrap user memory: invalid dmabuf from user.\n");
 
                 gcmkFOOTER();
                 return gcvSTATUS_INVALID_ARGUMENT;
@@ -3278,13 +4334,6 @@ gckVIDMEM_NODE_WrapUserMemory(
 
             dmabuf = gcmUINT64_TO_PTR(Desc->dmabuf);
         }
-        else
-        {
-            gcmkPRINT("Wrap memory: invalid dmabuf fd.\n");
-
-            gcmkFOOTER();
-            return gcvSTATUS_INVALID_ARGUMENT;
-        }
 
         if (dmabuf->ops == &_dmabuf_ops)
         {
@@ -3433,6 +4482,7 @@ gckVIDMEM_NODE_Find(
     gceSTATUS status = gcvSTATUS_NOT_FOUND;
     gckVIDMEM_NODE nodeObject = gcvNULL;
     gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
     gcsLISTHEAD_PTR pos;
     gceHARDWARE_TYPE hwType;
 
@@ -3449,6 +4499,7 @@ gckVIDMEM_NODE_Find(
     {
         nodeObject = (gckVIDMEM_NODE)gcmCONTAINEROF(pos, struct _gcsVIDMEM_NODE, link);
         node = nodeObject->node;
+        vidMemBlock = node->VirtualChunk.parent;
 
         if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
         {
@@ -3472,6 +4523,28 @@ gckVIDMEM_NODE_Find(
                 break;
             }
         }
+        else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+        {
+            if (!node->VirtualChunk.lockeds[hwType])
+            {
+                /* Don't check against unlocked node. */
+                continue;
+            }
+
+            if (Address >= node->VirtualChunk.addresses[hwType] &&
+                Address <= node->VirtualChunk.addresses[hwType] + node->VirtualChunk.bytes - 1)
+            {
+                *NodeObject = nodeObject;
+
+                if (Offset)
+                {
+                    *Offset = Address - node->VirtualChunk.addresses[hwType];
+                }
+
+                status = gcvSTATUS_OK;
+                break;
+            }
+        }
         else
         {
             if (!node->Virtual.lockeds[hwType])
index 3db7a009e2f9ac74aebaa2c09ed3503877c892dc..648875032e03e88917066d39622dc80d5a89f4ff 100644 (file)
@@ -53,7 +53,7 @@
 *****************************************************************************/
 
 
-/*Auto created on 2019-05-13 14:37*/
+/*Auto created on 2019-09-26 14:56*/
 #ifndef _gc_feature_database_h_
 #define _gc_feature_database_h_
 
@@ -95,6 +95,7 @@ typedef struct
     gctUINT32 NNCoreCount_INT8;
     gctUINT32 NNCoreCount_INT16;
     gctUINT32 NNCoreCount_FLOAT16;
+    gctUINT32 NNCoreCount_BFLOAT;
     gctUINT32 NNInputBufferDepth;
     gctUINT32 NNAccumBufferDepth;
     gctUINT32 TPEngine_PwlLUTCount;
@@ -485,6 +486,7 @@ typedef struct
     gctUINT32 SHARE_Z:1;
     gctUINT32 DE_2D_FAST_CLEAR:1;
     gctUINT32 TX_CLEAR_PENDING_FIX:1;
+    gctUINT32 NO_HI1_L2:1;
     gctUINT32 VG_TS_CULLING:1;
     gctUINT32 VG_FP25:1;
     gctUINT32 VG_AYUV_INPUT_OUTPUT:1;
@@ -578,6 +580,7 @@ typedef struct
     gctUINT32 NN_WRITE_WITHOUT_USC:1;
     gctUINT32 NN_ZDP_INIMAGE_SIZE_FIX:1;
     gctUINT32 HI_REORDER_FIX:1;
+    gctUINT32 INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX:1;
     gctUINT32 TP_COEF_COMPRESSION_ENHANCEMENT:1;
     gctUINT32 VIP_DEC400:1;
     gctUINT32 IMAGE_NOT_PACKED_IN_SRAM_FIX:1;
@@ -591,9 +594,22 @@ typedef struct
     gctUINT32 USC_BOTTLENECK_FIX:1;
     gctUINT32 KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX:1;
     gctUINT32 FULLCACHE_KERNEL_INTERLEAVE_FIX:1;
+    gctUINT32 TP_REORDER_LAYER_SUSPEND_FIX:1;
+    gctUINT32 KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX:1;
+    gctUINT32 IMG_POP_PIPELINE_PAUSE_FIX:1;
+    gctUINT32 DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX:1;
+    gctUINT32 OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX:1;
     gctUINT32 NN_PER_CHANNEL_POST_MULTIPLY:1;
     gctUINT32 NN_NO_Z_LOCATION_OFFSET:1;
     gctUINT32 NN_PRELU:1;
+    gctUINT32 OCB_REMAP_PHYSICAL_ADDRESS:1;
+    gctUINT32 NN_SLICE_PADDING_TO_64BYTE_ALIGN:1;
+    gctUINT32 NN_DW_1x1_CONV_MERGE:1;
+    gctUINT32 NN_SLOW_OUTPUT:1;
+    gctUINT32 NO_NARROW_POST_PROCESS_PIPE:1;
+    gctUINT32 TP_NN_PROBE:1;
+    gctUINT32 TP_23BITS_POST_MULTIPLIER:1;
+    gctUINT32 NN_TRANSPOSE:1;
 } gcsFEATURE_DATABASE;
 
 static gcsFEATURE_DATABASE gChipInfo[] = {
@@ -634,6 +650,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -1024,6 +1041,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -1117,6 +1135,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -1128,11 +1147,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x0, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
     /* vipnano-qi */
     {
@@ -1171,6 +1203,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -1561,6 +1594,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -1654,6 +1688,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -1665,11 +1700,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x0, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
     /* vipnano-qi */
     {
@@ -1708,6 +1756,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -2098,6 +2147,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -2191,6 +2241,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -2202,11 +2253,577 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x0, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
+    },
+    /* vipnano-qi */
+    {
+        0x8000, /* ChipID */
+        0x7131, /* ChipRevision */
+        0x5000009, /* ProductID */
+        0x8000000, /* EcoID */
+        0xa1, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x43f000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x1, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
     /* vippico_v3 */
     {
@@ -2245,6 +2862,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_BFLOAT */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
@@ -2635,6 +3253,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SHARE_Z */
         0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_TX_CLEAR_PENDING_FIX */
+        0x0, /* gcFEATURE_BIT_NO_HI1_L2 */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -2728,6 +3347,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
         0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
@@ -2739,11 +3359,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
         0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_USC_BOTTLENECK_FIX */
-        0x1, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNEL_INTERLEAVE_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_LAYER_SUSPEND_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_IMG_POP_PIPELINE_PAUSE_FIX */
+        0x1, /* gcFEATURE_BIT_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX */
+        0x1, /* gcFEATURE_BIT_OUTIMAGE_X_BITWIDTH_LIMIT_FOR_NN_TRANSPOSE_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
         0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
         0x0, /* gcFEATURE_BIT_NN_PRELU */
+        0x1, /* gcFEATURE_BIT_OCB_REMAP_PHYSICAL_ADDRESS */
+        0x0, /* gcFEATURE_BIT_NN_SLICE_PADDING_TO_64BYTE_ALIGN */
+        0x0, /* gcFEATURE_BIT_NN_DW_1x1_CONV_MERGE */
+        0x0, /* gcFEATURE_BIT_NN_SLOW_OUTPUT */
+        0x0, /* gcFEATURE_BIT_NO_NARROW_POST_PROCESS_PIPE */
+        0x0, /* gcFEATURE_BIT_TP_NN_PROBE */
+        0x0, /* gcFEATURE_BIT_TP_23BITS_POST_MULTIPLIER */
+        0x0, /* gcFEATURE_BIT_NN_TRANSPOSE */
     },
 };
 
index deeb9be2df3aeaffff4d26238aa6ed1e87f60ae2..00c806bc3787140ff19d53b48abcbb657f964f88 100644 (file)
@@ -56,7 +56,6 @@
 #ifndef __gc_hal_h_
 #define __gc_hal_h_
 
-#include "gc_hal_rename.h"
 #include "gc_hal_types.h"
 #include "gc_hal_enum.h"
 #include "gc_hal_base.h"
@@ -92,12 +91,6 @@ extern "C" {
          (n) : gcmALIGN(n, align)                                      \
 )
 
-#define gcmALIGN_CHECK_OVERFLOW(n, align)                              \
-(\
-    (gcmALIGN((n) & ~0ULL, (align) & ~0ULL) ^ gcmALIGN(n, align)) ?    \
-         gcvSTATUS_RESLUT_OVERFLOW : gcvSTATUS_OK                      \
-)
-
 #define gcmALIGN_BASE(n, align) \
 (\
     ((n) & ~((align) - 1)) \
@@ -210,6 +203,7 @@ typedef enum _gceOBJECT_TYPE
     gcvOBJ_VARIABLE             = gcmCC('V','A','R','I'),
     gcvOBJ_VERTEX               = gcmCC('V','R','T','X'),
     gcvOBJ_VIDMEM               = gcmCC('V','M','E','M'),
+    gcvOBJ_VIDMEM_BLOCK         = gcmCC('V','M','B','K'),
     gcvOBJ_VG                   = gcmCC('V','G',' ',' '),
     gcvOBJ_BUFOBJ               = gcmCC('B','U','F','O'),
     gcvOBJ_UNIFORM_BLOCK        = gcmCC('U','B','L','K'),
@@ -415,6 +409,19 @@ gckOS_MapPagesEx(
     IN gceVIDMEM_TYPE Type
     );
 
+/* Map 1M pages. */
+gceSTATUS
+gckOS_Map1MPages(
+    IN gckOS Os,
+    IN gceCORE Core,
+    IN gctPHYS_ADDR Physical,
+    IN gctSIZE_T PageCount,
+    IN gctUINT32 Address,
+    IN gctPOINTER PageTable,
+    IN gctBOOL Writable,
+    IN gceVIDMEM_TYPE Type
+    );
+
 gceSTATUS
 gckOS_UnmapPages(
     IN gckOS Os,
@@ -568,6 +575,20 @@ gckOS_WriteRegisterEx_NoDump(
     IN gctUINT32 Data
     );
 
+#ifdef __QNXNTO__
+static gcmINLINE gceSTATUS
+gckOS_WriteMemory(
+    IN gckOS Os,
+    IN gctPOINTER Address,
+    IN gctUINT32 Data
+    )
+{
+    /* Write memory. */
+    *(gctUINT32 *)Address = Data;
+    return gcvSTATUS_OK;
+}
+
+#else
 /* Write data to a 32-bit memory location. */
 gceSTATUS
 gckOS_WriteMemory(
@@ -575,6 +596,7 @@ gckOS_WriteMemory(
     IN gctPOINTER Address,
     IN gctUINT32 Data
     );
+#endif
 
 /* Map physical memory into the process space. */
 gceSTATUS
@@ -1567,7 +1589,6 @@ gckHEAP_ProfileEnd(
     IN gctCONST_STRING Title
     );
 
-
 typedef struct _gckVIDMEM *         gckVIDMEM;
 typedef struct _gckKERNEL *         gckKERNEL;
 typedef struct _gckDB *             gckDB;
@@ -1971,21 +1992,21 @@ gckHARDWARE_ReadInterrupt(
 
 /* Power management. */
 gceSTATUS
-gckHARDWARE_SetPowerManagementState(
+gckHARDWARE_SetPowerState(
     IN gckHARDWARE Hardware,
     IN gceCHIPPOWERSTATE State
     );
 
 gceSTATUS
-gckHARDWARE_QueryPowerManagementState(
+gckHARDWARE_QueryPowerState(
     IN gckHARDWARE Hardware,
     OUT gceCHIPPOWERSTATE* State
     );
 
 gceSTATUS
-gckHARDWARE_SetPowerManagement(
+gckHARDWARE_EnablePowerManagement(
     IN gckHARDWARE Hardware,
-    IN gctBOOL PowerManagement
+    IN gctBOOL Enable
     );
 
 gceSTATUS
@@ -2016,20 +2037,6 @@ gckHARDWARE_SetMinFscaleValue(
     );
 #endif
 
-#if gcdPOWEROFF_TIMEOUT
-gceSTATUS
-gckHARDWARE_SetPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    IN gctUINT32    Timeout
-);
-
-gceSTATUS
-gckHARDWARE_QueryPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    OUT gctUINT32*  Timeout
-);
-#endif
-
 gceSTATUS
 gckHARDWARE_InitializeHardware(
     IN gckHARDWARE Hardware
@@ -2150,6 +2157,7 @@ gceSTATUS
 gckMMU_AllocatePages(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
+    IN gcePAGE_TYPE PageType,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
     );
@@ -2159,6 +2167,7 @@ gckMMU_AllocatePagesEx(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
     IN gceVIDMEM_TYPE Type,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
@@ -2169,6 +2178,7 @@ gceSTATUS
 gckMMU_FreePages(
     IN gckMMU Mmu,
     IN gctBOOL Secure,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctSIZE_T PageCount
@@ -2179,6 +2189,7 @@ gceSTATUS
 gckMMU_SetPage(
    IN gckMMU Mmu,
    IN gctPHYS_ADDR_T PageAddress,
+   IN gcePAGE_TYPE PageType,
    IN gctBOOL Writable,
    IN gctUINT32 *PageEntry
    );
@@ -2192,6 +2203,7 @@ gckMMU_Flush(
 gceSTATUS
 gckMMU_DumpPageTableEntry(
     IN gckMMU Mmu,
+    IN gceAREA_TYPE AreaType,
     IN gctUINT32 Address
     );
 
@@ -2205,10 +2217,17 @@ gckMMU_FillFlatMapping(
 gceSTATUS
 gckMMU_IsFlatMapped(
     IN gckMMU Mmu,
-    OUT gctUINT64 Physical,
+    IN gctUINT64 Physical,
+    IN gctUINT32 Address,
     OUT gctBOOL *In
     );
 
+gceSTATUS
+gckMMU_GetAreaType(
+    IN gckMMU Mmu,
+    IN gctUINT32 GpuAddress,
+    OUT gceAREA_TYPE *AreaType
+    );
 
 gceSTATUS
 gckHARDWARE_QueryContextProfile(
index 23076eb7f88f75a21d331039e8788619008caefc..9c0c6986cb97627f211e16ced8abf764056816d5 100644 (file)
@@ -58,6 +58,7 @@
 
 #include "gc_hal_enum.h"
 #include "gc_hal_types.h"
+#include "gc_hal_debug_zones.h"
 
 
 #ifdef __cplusplus
@@ -89,6 +90,7 @@ typedef struct _gcsBOUNDARY *           gcsBOUNDARY_PTR;
 typedef struct _gcoHARDWARE *           gcoHARDWARE;
 typedef union  _gcuVIDMEM_NODE *        gcuVIDMEM_NODE_PTR;
 typedef struct _gcsVIDMEM_NODE *        gckVIDMEM_NODE;
+typedef struct _gcsVIDMEM_BLOCK *       gckVIDMEM_BLOCK;
 
 typedef void *                          gcoVG;
 
@@ -113,6 +115,7 @@ typedef struct _gcsNN_FIXED_FEATURE
     gctUINT  nnCoreCountInt8;       /* total nn core count supporting int8 */
     gctUINT  nnCoreCountInt16;      /* total nn core count supporting int16 */
     gctUINT  nnCoreCountFloat16;    /* total nn core count supporting float16 */
+    gctUINT  nnCoreCountBFloat16;    /* total nn core count supporting Bfloat16 */
     gctUINT  nnMadPerCore;
     gctUINT  nnInputBufferDepth;
     gctUINT  nnAccumBufferDepth;
@@ -189,7 +192,10 @@ typedef struct _gcsNN_UNIFIED_FEATURE
     gctUINT  axiSramOnlySWTiling : 1;
     gctUINT  imageNotPackedInSram : 1;
     gctUINT  coefDeltaCordOverFlowZRL8BitFix : 1;
+    gctUINT  lowEfficiencyOfIDWriteImgBufFix : 1;
     gctUINT  xyOffsetLimitationFix : 1;
+    gctUINT  kernelPerCoreLTOneThirdCoefFix : 1;
+    gctUINT  diffConditionForCachelineModePreFix : 1;
 } gcsNN_UNIFIED_FEATURE;
 
 /* Features are derived from above ones */
@@ -366,6 +372,8 @@ typedef enum _gcePOOL
     gcvPOOL_SRAM,
     gcvPOOL_VIRTUAL,
     gcvPOOL_USER,
+    gcvPOOL_INTERNAL_SRAM,
+    gcvPOOL_EXTERNAL_SRAM,
 
     gcvPOOL_NUMBER_OF_POOLS
 }
@@ -496,6 +504,20 @@ typedef struct _gcsHAL_LIMITS
 
 }gcsHAL_LIMITS;
 
+
+typedef struct _gcsHAL_CHIPIDENTITY
+{
+    gceCHIPMODEL                chipModel;
+    gctUINT32                   chipRevision;
+    gctUINT32                   productID;
+    gctUINT32                   customerID;
+    gctUINT32                   ecoID;
+    gceCHIP_FLAG                chipFlags;
+    gctUINT64                   platformFlagBits;
+}
+gcsHAL_CHIPIDENTITY;
+
+
 #define gcdEXTERNAL_MEMORY_NAME_MAX 32
 #define gcdEXTERNAL_MEMORY_DATA_MAX 8
 
@@ -660,6 +682,12 @@ gcoHAL_QueryChipIdentity(
     OUT gctUINT32* ChipMinorFeatures
     );
 
+gceSTATUS gcoHAL_QueryChipIdentityEx(
+    IN gcoHAL Hal,
+    IN gctUINT32 SizeOfParam,
+    OUT gcsHAL_CHIPIDENTITY *ChipIdentity
+    );
+
 
 gceSTATUS
 gcoHAL_QuerySuperTileMode(
@@ -681,9 +709,12 @@ gcoHAL_QueryMultiGPUAffinityConfig(
 gceSTATUS
 gcoHAL_QuerySRAM(
     IN gcoHAL Hal,
-    IN gceSRAM Type,
-    OUT gctUINT32 *Base,
-    OUT gctUINT32 *Size
+    IN gcePOOL Type,
+    OUT gctUINT32 *Size,
+    OUT gctUINT32 *GPUVirtAddr,
+    OUT gctPHYS_ADDR_T *GPUPhysAddr,
+    OUT gctUINT32 *GPUPhysName,
+    OUT gctPHYS_ADDR_T *CPUPhysAddr
     );
 
 #ifdef LINUX
@@ -893,7 +924,8 @@ gcoHAL_QueryCluster(
     IN gcoHAL       Hal,
     OUT gctINT32   *ClusterMinID,
     OUT gctINT32   *ClusterMaxID,
-    OUT gctUINT32  *ClusterCount
+    OUT gctUINT32  *ClusterCount,
+    OUT gctUINT32  *ClusterIDWidth
     );
 
 gceSTATUS
@@ -1097,6 +1129,14 @@ gcoHAL_GetGraphicBufferFd(
     OUT gctINT32 * Fd
     );
 
+gceSTATUS
+gcoHAL_AlignToTile(
+    IN OUT gctUINT32 * Width,
+    IN OUT gctUINT32 * Height,
+    IN  gceSURF_TYPE Type,
+    IN  gceSURF_FORMAT Format
+    );
+
 /******************************************************************************\
 ********************************** gcoOS Object *********************************
 \******************************************************************************/
@@ -2337,6 +2377,9 @@ typedef struct _gcsSURF_FORMAT_INFO
     /* sRGB format. */
     gctBOOL                     sRGB;
 
+    /* How GPU read from big-endian host memory */
+    gceENDIAN_HINT              endian;
+
     /* Format components. */
     gcuPIXEL_FORMAT_CLASS       u;
 
@@ -2425,7 +2468,10 @@ gcoSURF_QueryVidMemNode(
     IN gcoSURF Surface,
     OUT gctUINT32 * Node,
     OUT gcePOOL * Pool,
-    OUT gctSIZE_T_PTR Bytes
+    OUT gctSIZE_T_PTR Bytes,
+    OUT gctUINT32 * TsNode,
+    OUT gcePOOL * TsPool,
+    OUT gctSIZE_T_PTR TsBytes
     );
 
 /* Set the color type of the surface. */
@@ -2931,6 +2977,12 @@ gcoSURF_WrapUserMultiBuffer(
     OUT gcoSURF * Surface
     );
 
+gceSTATUS
+gcoSURF_UpdateMetadata(
+    IN gcoSURF Surface,
+    IN gctINT TsFD
+    );
+
 #define MAX_SURF_MIX_SRC_NUM 64
 gceSTATUS
 gcoSURF_MixSurfacesCPU(
@@ -3108,7 +3160,6 @@ gcoHEAP_ProfileEnd(
     );
 #endif
 
-
 /******************************************************************************\
 ******************************* Debugging Macros *******************************
 \******************************************************************************/
@@ -3123,11 +3174,6 @@ gcoOS_GetDebugLevel(
     OUT gctUINT32_PTR DebugLevel
     );
 
-void
-gcoOS_SetDebugZone(
-    IN gctUINT32 Zone
-    );
-
 void
 gcoOS_GetDebugZone(
     IN gctUINT32 Zone,
@@ -3135,17 +3181,10 @@ gcoOS_GetDebugZone(
     );
 
 void
-gcoOS_SetDebugLevelZone(
-    IN gctUINT32 Level,
+gcoOS_SetDebugZone(
     IN gctUINT32 Zone
     );
 
-void
-gcoOS_SetDebugZones(
-    IN gctUINT32 Zones,
-    IN gctBOOL Enable
-    );
-
 void
 gcoOS_SetDebugFile(
     IN gctCONST_STRING FileName
@@ -3272,80 +3311,6 @@ gcoOS_DebugTrace(
 #   define gcmkTRACE_N          __dummy_trace_n
 #endif
 
-/* Zones common for kernel and user. */
-#define gcvZONE_OS              (1 << 0)
-#define gcvZONE_HARDWARE        (1 << 1)
-#define gcvZONE_HEAP            (1 << 2)
-#define gcvZONE_SIGNAL          (1 << 3)
-
-/* Kernel zones. */
-#define gcvZONE_KERNEL          (1 << 4)
-#define gcvZONE_VIDMEM          (1 << 5)
-#define gcvZONE_COMMAND         (1 << 6)
-#define gcvZONE_DRIVER          (1 << 7)
-#define gcvZONE_CMODEL          (1 << 8)
-#define gcvZONE_MMU             (1 << 9)
-#define gcvZONE_EVENT           (1 << 10)
-#define gcvZONE_DEVICE          (1 << 11)
-#define gcvZONE_DATABASE        (1 << 12)
-#define gcvZONE_INTERRUPT       (1 << 13)
-#define gcvZONE_POWER           (1 << 14)
-#define gcvZONE_ASYNC_COMMAND   (1 << 15)
-#define gcvZONE_ALLOCATOR       (1 << 16)
-
-/* User zones. */
-#define gcvZONE_HAL             (1 << 4)
-#define gcvZONE_BUFFER          (1 << 5)
-#define gcvZONE_CONTEXT         (1 << 6)
-#define gcvZONE_SURFACE         (1 << 7)
-#define gcvZONE_INDEX           (1 << 8)
-#define gcvZONE_STREAM          (1 << 9)
-#define gcvZONE_TEXTURE         (1 << 10)
-#define gcvZONE_2D              (1 << 11)
-#define gcvZONE_3D              (1 << 12)
-#define gcvZONE_COMPILER        (1 << 13)
-#define gcvZONE_MEMORY          (1 << 14)
-#define gcvZONE_STATE           (1 << 15)
-#define gcvZONE_AUX             (1 << 16)
-#define gcvZONE_VERTEX          (1 << 17)
-#define gcvZONE_CL              (1 << 18)
-#define gcvZONE_VG              (1 << 19)
-#define gcvZONE_VX              (1 << 20)
-#define gcvZONE_IMAGE           (1 << 21)
-#define gcvZONE_UTILITY         (1 << 22)
-#define gcvZONE_PARAMETERS      (1 << 23)
-#define gcvZONE_BUFOBJ          (1 << 24)
-#define gcvZONE_SHADER          (1 << 25)
-#define gcvZONE_STREAM_OUT      (1 << 26)
-
-/* API definitions. */
-#define gcvZONE_API_HAL         ((gctUINT32) 1  << 28)
-#define gcvZONE_API_EGL         ((gctUINT32) 2  << 28)
-#define gcvZONE_API_ES11        ((gctUINT32) 3  << 28)
-#define gcvZONE_API_ES20        ((gctUINT32) 4  << 28)
-#define gcvZONE_API_ES30        ((gctUINT32) 4  << 28)
-#define gcvZONE_API_VG11        ((gctUINT32) 5  << 28)
-#define gcvZONE_API_GL          ((gctUINT32) 6  << 28)
-#define gcvZONE_API_DFB         ((gctUINT32) 7  << 28)
-#define gcvZONE_API_GDI         ((gctUINT32) 8  << 28)
-#define gcvZONE_API_D3D         ((gctUINT32) 9  << 28)
-#define gcvZONE_API_CL          ((gctUINT32) 10 << 28)
-#define gcvZONE_API_VX          ((gctUINT32) 11 << 28)
-
-
-#define gcmZONE_GET_API(zone)   ((zone) >> 28)
-/*Set gcdZONE_MASE like 0x0 | gcvZONE_API_EGL
-will enable print EGL module debug info*/
-#define gcdZONE_MASK            0x0FFFFFFF
-
-/* Handy zones. */
-#define gcvZONE_NONE            0
-#define gcvZONE_ALL             0x0FFFFFFF
-
-/*Dump API depth set 1 for API, 2 for API and API behavior*/
-#define gcvDUMP_API_DEPTH       1
-
-
 /*******************************************************************************
 **
 **  gcmTRACE_ZONE
@@ -4403,8 +4368,8 @@ gckOS_DebugBreak(
 #   define gcmVERIFY(exp)           gcmASSERT(exp)
 #   define gcmkVERIFY(exp)          gcmkASSERT(exp)
 #else
-#   define gcmVERIFY(exp)           exp
-#   define gcmkVERIFY(exp)          exp
+#   define gcmVERIFY(exp)           (void)exp
+#   define gcmkVERIFY(exp)          (void)exp
 #endif
 
 /*******************************************************************************
@@ -4463,8 +4428,8 @@ gckOS_Verify(
         } \
         while (gcvFALSE)
 #else
-#   define gcmVERIFY_OK(func)       (void)func
-#   define gcmkVERIFY_OK(func)      (void)func
+#   define gcmVERIFY_OK(func)       func
+#   define gcmkVERIFY_OK(func)      func
 #endif
 
 gctCONST_STRING
@@ -4491,7 +4456,7 @@ gckOS_DebugStatus2Name(
 **
 **      func    Function to evaluate.
 */
-#define _gcmERR_BREAK(prefix, func) \
+#define _gcmERR_BREAK(prefix, func){ \
     status = func; \
     if (gcmIS_ERROR(status)) \
     { \
@@ -4501,8 +4466,10 @@ gckOS_DebugStatus2Name(
             status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
         break; \
     } \
-    do { } while (gcvFALSE)
-#define _gcmkERR_BREAK(prefix, func) \
+    do { } while (gcvFALSE); \
+    }
+
+#define _gcmkERR_BREAK(prefix, func){ \
     status = func; \
     if (gcmIS_ERROR(status)) \
     { \
@@ -4512,7 +4479,9 @@ gckOS_DebugStatus2Name(
             status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
         break; \
     } \
-    do { } while (gcvFALSE)
+    do { } while (gcvFALSE); \
+    }
+
 #define gcmERR_BREAK(func)          _gcmERR_BREAK(gcm, func)
 #define gcmkERR_BREAK(func)         _gcmkERR_BREAK(gcmk, func)
 
@@ -4887,14 +4856,6 @@ gckOS_DebugStatus2Name(
 #   define gcmkVERIFY_ARGUMENT_RETURN(arg, value) \
                 _gcmVERIFY_ARGUMENT_RETURN(gcmk, arg, value)
 
-#define _gcmCHECK_ADD_OVERFLOW(x, y) \
-(\
-    ((x) > 0 && (y) > 0 && gcvMAXSIZE_T - (x) < (y)) ? gcvSTATUS_RESLUT_OVERFLOW : gcvSTATUS_OK \
-)
-
-#define gcmCHECK_ADD_OVERFLOW(x, y) _gcmCHECK_ADD_OVERFLOW(x, y)
-#define gcmkCHECK_ADD_OVERFLOW(x, y) _gcmCHECK_ADD_OVERFLOW(x, y)
-
 #define MAX_LOOP_COUNT 0x7FFFFFFF
 
 /******************************************************************************\
@@ -5011,46 +4972,12 @@ gcoHAL_GetUserDebugOption(
 
 #endif
 
-#if gcdSECURE_USER
-
-#   define gcmDEFINESECUREUSER() \
-        gctUINT         __secure_user_offset__; \
-        gctUINT32_PTR   __secure_user_hintArray__;
-
-#   define gcmBEGINSECUREUSER() \
-        __secure_user_offset__ = reserve->lastOffset; \
-        \
-        __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
-
-#   define gcmENDSECUREUSER() \
-        reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
-
-#   define gcmSKIPSECUREUSER() \
-        __secure_user_offset__ += gcmSIZEOF(gctUINT32)
-
-#   define gcmUPDATESECUREUSER() \
-        *__secure_user_hintArray__ = __secure_user_offset__; \
-        \
-        __secure_user_offset__    += gcmSIZEOF(gctUINT32); \
-        __secure_user_hintArray__ += 1
-
-#else
-
-#   define gcmDEFINESECUREUSER()
-#   define gcmBEGINSECUREUSER()
-#   define gcmENDSECUREUSER()
-#   define gcmSKIPSECUREUSER()
-#   define gcmUPDATESECUREUSER()
-
-#endif
-
 /*----------------------------------------------------------------------------*/
 
 /* This style of dump is deprecated. */
 #   define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
 
 #define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
-    gcmDEFINESECUREUSER() \
     gctSIZE_T ReserveSize; \
     gcoCMDBUF CommandBuffer; \
     gctUINT32_PTR Memory; \
@@ -5067,13 +4994,10 @@ gcoHAL_GetUserDebugOption(
     \
     StateDelta = Hardware->delta; \
     \
-    gcmBEGINSECUREUSER(); \
 }
 
 #define gcmENDSTATEBUFFER(Hardware, CommandBuffer, Memory, ReserveSize) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     gcmASSERT(\
         gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
         == \
@@ -5097,8 +5021,6 @@ gcoHAL_GetUserDebugOption(
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmENDSTATEBATCH(CommandBuffer, Memory) \
@@ -5126,8 +5048,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5146,8 +5066,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 
@@ -5162,8 +5080,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETFILLER(CommandBuffer, Memory) \
@@ -5172,8 +5088,6 @@ gcoHAL_GetUserDebugOption(
     \
     *(gctUINT32_PTR)Memory = 0x18000000; \
     Memory += 1; \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*----------------------------------------------------------------------------*/
@@ -5218,8 +5132,6 @@ gcoHAL_GetUserDebugOption(
     gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*******************************************************************************
@@ -5248,7 +5160,6 @@ gcoHAL_GetUserDebugOption(
 ** Temp command buffer macro
 */
 #define gcmDEFINESTATEBUFFER_NEW(CommandBuffer, StateDelta, Memory) \
-    gcmDEFINESECUREUSER() \
     gcmDEFINELOADSTATEBASE() \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
     gctUINT32_PTR Memory; \
@@ -5271,16 +5182,13 @@ gcoHAL_GetUserDebugOption(
         Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
         \
     }\
-    StateDelta = Hardware->delta; \
+    StateDelta = Hardware->tempDelta; \
     \
-    gcmBEGINSECUREUSER(); \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
 }
 
 #define gcmENDSTATEBUFFER_NEW(Hardware, CommandBuffer, Memory, OutSide) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     if (OutSide) \
     {\
         *OutSide = Memory; \
@@ -5291,12 +5199,15 @@ gcoHAL_GetUserDebugOption(
                                          (gctUINT8_PTR)CommandBuffer->buffer); \
         \
         gcmONERROR(gcoBUFFER_EndTEMPCMDBUF(Hardware->engine[CurrentEngine].buffer, gcvFALSE));\
+        if (Hardware->constructType != gcvHARDWARE_2D) \
+        { \
+            gcoHARDWARE_UpdateTempDelta(Hardware);\
+        } \
     }\
     gcmUNSETLOADSTATEBASE()\
 }
 
 #define gcmDEFINECTRLSTATEBUFFER(CommandBuffer, Memory)                         \
-    gcmDEFINESECUREUSER()                                                       \
     gcmDEFINELOADSTATEBASE()                                                    \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL;                                      \
     gctUINT32_PTR Memory;                                                       \
@@ -5317,7 +5228,6 @@ gcoHAL_GetUserDebugOption(
                                                                                 \
         Memory = (gctUINT32_PTR)(CommandBuffer->buffer);                        \
     }                                                                           \
-    gcmBEGINSECUREUSER();                                                       \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);                                 \
 }
 
@@ -5333,8 +5243,6 @@ gcoHAL_GetUserDebugOption(
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmENDSTATEBATCH_NEW(CommandBuffer, Memory) \
@@ -5356,8 +5264,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5374,8 +5280,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 
@@ -5388,16 +5292,12 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETFILLER_NEW(CommandBuffer, Memory) \
 { \
     *(gctUINT32_PTR)Memory = 0x18000000; \
     Memory += 1; \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*----------------------------------------------------------------------------*/
@@ -5442,8 +5342,6 @@ gcoHAL_GetUserDebugOption(
     gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETSTARTDECOMMAND_NEW(CommandBuffer, Memory, Count) \
@@ -5467,8 +5365,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5481,8 +5377,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSINGLESTATE_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5515,8 +5409,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5531,8 +5423,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSINGLESTATE_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5554,13 +5444,11 @@ gcoHAL_GetUserDebugOption(
 }
 
 #define gcmDEFINESTATEBUFFER_NEW_FAST(CommandBuffer, Memory) \
-    gcmDEFINESECUREUSER() \
     gcmDEFINELOADSTATEBASE() \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
     gctUINT32_PTR Memory;
 
 #define gcmDEFINESTATEBUFFER_FAST(CommandBuffer, Memory, ReserveSize) \
-    gcmDEFINESECUREUSER() \
     gctSIZE_T ReserveSize; \
     gcoCMDBUF CommandBuffer; \
     gctUINT32_PTR Memory;
@@ -5573,7 +5461,6 @@ gcoHAL_GetUserDebugOption(
     \
     Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
     \
-    gcmBEGINSECUREUSER(); \
 }
 
 #define gcmBEGINSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
@@ -5592,14 +5479,11 @@ gcoHAL_GetUserDebugOption(
         \
     }\
     \
-    gcmBEGINSECUREUSER(); \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
 }
 
 #define gcmENDSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     if (OutSide) \
     {\
         *OutSide = Memory; \
@@ -5748,6 +5632,97 @@ gcoHAL_GetUserDebugOption(
 }
 #endif
 
+/*******************************************************************************
+**
+**  gcmCONFIGUREUNIFORMS2
+**  only fix clang build error
+**
+**      Configure uniforms according to chip and numConstants.
+*/
+#if !gcdENABLE_UNIFIED_CONSTANT
+#define gcmCONFIGUREUNIFORMS2(ChipModel, ChipRevision, NumConstants, \
+             UnifiedConst, VsConstMax, PsConstMax) \
+{ \
+    if (ChipModel == gcv2000 && (ChipRevision == 0x5118 || ChipRevision == 0x5140)) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 64; \
+    } \
+    else if (NumConstants == 320) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 64; \
+    } \
+    /* All GC1000 series chips can only support 64 uniforms for ps on non-unified const mode. */ \
+    else if (NumConstants > 256 && ChipModel == gcv1000) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 64; \
+    } \
+    else if (NumConstants > 256) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 256; \
+    } \
+    else if (NumConstants == 256) \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 256; \
+        PsConstMax   = 256; \
+    } \
+    else \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 168; \
+        PsConstMax   = 64; \
+    } \
+}
+#else
+#define gcmCONFIGUREUNIFORMS2(ChipModel, ChipRevision, Halti5Avail, SmallBatch, NumConstants, \
+             UnifiedConst, VsConstMax, PsConstMax) \
+{ \
+    if (NumConstants > 256) \
+    { \
+        UnifiedConst = gcvTRUE; \
+        if ((ChipModel == gcv880) && ((ChipRevision & 0xfff0) == 0x5120)) \
+        { \
+            VsConstMax   = 512; \
+            PsConstMax   = 64; \
+        } \
+        else \
+        { \
+            VsConstMax   = gcmMIN(512, NumConstants - 64); \
+            PsConstMax   = gcmMIN(512, NumConstants - 64); \
+        } \
+    } \
+    else if (NumConstants == 256) \
+    { \
+        if (ChipModel == gcv2000 && (ChipRevision == 0x5118 || ChipRevision == 0x5140)) \
+        { \
+            UnifiedConst = gcvFALSE; \
+            VsConstMax   = 256; \
+            PsConstMax   = 64; \
+        } \
+        else \
+        { \
+            UnifiedConst = gcvFALSE; \
+            VsConstMax   = 256; \
+            PsConstMax   = 256; \
+        } \
+    } \
+    else \
+    { \
+        UnifiedConst = gcvFALSE; \
+        VsConstMax   = 168; \
+        PsConstMax   = 64; \
+    } \
+}
+#endif
+
 #define gcmAnyTileStatusEnableForFullMultiSlice(SurfView, anyTsEnableForMultiSlice)\
 {\
     gctUINT i = 0; \
@@ -5853,7 +5828,15 @@ gcoHAL_GetUserDebugOption(
                     prefix##ASSERT(!featureGS); \
                     attribBufSizeInKB = 8; \
                 } \
-                L1cacheSize = featureUSCMaxPages - attribBufSizeInKB; \
+                if (attribBufSizeInKB < featureUSCMaxPages) \
+                { \
+                    L1cacheSize = featureUSCMaxPages - attribBufSizeInKB; \
+                } \
+                else \
+                { \
+                    attribBufSizeInKB -= 2; \
+                    L1cacheSize = 2; \
+                } \
             } \
             prefix##ASSERT(L1cacheSize); \
             if (L1cacheSize >= featureL1CacheSize) \
@@ -5897,6 +5880,88 @@ gcoHAL_GetUserDebugOption(
     } \
 } \
 
+#define gcmCONFIGUSC2(prefix, featureUSC, featureSeparateLS, featureComputeOnly, \
+    featureTS, featureL1CacheSize, featureUSCMaxPages, \
+    attribCacheRatio, L1CacheRatio) \
+{ \
+    attribCacheRatio = 0x2; \
+    \
+    if (featureUSC) \
+    { \
+        if (featureSeparateLS) \
+        { \
+            L1CacheRatio = 0x0; \
+        } \
+        else \
+        { \
+            gctUINT L1cacheSize; \
+            \
+            if (featureComputeOnly) \
+            { \
+                L1cacheSize = featureL1CacheSize; \
+            } \
+            else \
+            { \
+                gctUINT attribBufSizeInKB; \
+                if (featureTS) \
+                { \
+                    /* GS/TS must be bundled. */ \
+                    attribBufSizeInKB = 42; \
+                } \
+                else \
+                { \
+                    attribBufSizeInKB = 8; \
+                } \
+                if (attribBufSizeInKB < featureUSCMaxPages) \
+                { \
+                    L1cacheSize = featureUSCMaxPages - attribBufSizeInKB; \
+                } \
+                else \
+                { \
+                    attribBufSizeInKB -= 4; \
+                    L1cacheSize = 4; \
+                } \
+            } \
+            prefix##ASSERT(L1cacheSize); \
+            if (L1cacheSize >= featureL1CacheSize) \
+            { \
+                L1CacheRatio = 0x0; \
+            } \
+            else \
+            { \
+                static const gctINT s_uscCacheRatio[] = \
+                { \
+                    100000,/* 1.0f */     \
+                    50000, /* 0.5f */     \
+                    25000, /* 0.25f */    \
+                    12500, /* 0.125f */   \
+                    62500, /* 0.0625f */  \
+                    3125, /* 0.03125f */ \
+                    75000, /* 0.75f */    \
+                    0, /*0.0f */      \
+                }; \
+                gctINT maxL1cacheSize = L1cacheSize * 100000; \
+                gctINT delta = 2147483647; /* start with very big delta */ \
+                gctINT i = 0; \
+                gctINT curIndex = -1; \
+                for (; i < gcmCOUNTOF(s_uscCacheRatio); ++i) \
+                { \
+                    gctINT curL1cacheSize = featureL1CacheSize * s_uscCacheRatio[i]; \
+                  \
+                    if ((maxL1cacheSize >= curL1cacheSize) && \
+                        ((maxL1cacheSize - curL1cacheSize) < delta)) \
+                    { \
+                        curIndex = i; \
+                        delta = maxL1cacheSize - curL1cacheSize; \
+                    } \
+                } \
+                prefix##ASSERT(-1 != curIndex); \
+                L1CacheRatio = curIndex; \
+            } \
+        } \
+    } \
+} \
+
 #if VIVANTE_PROFILER_SYSTEM_MEMORY
 typedef struct _memory_profile_info
 {
diff --git a/drivers/amlogic/npu/kernel/inc/gc_hal_debug_zones.h b/drivers/amlogic/npu/kernel/inc/gc_hal_debug_zones.h
new file mode 100644 (file)
index 0000000..f0fbf9e
--- /dev/null
@@ -0,0 +1,329 @@
+/****************************************************************************
+*
+*    The MIT License (MIT)
+*
+*    Copyright (c) 2014 - 2019 Vivante Corporation
+*
+*    Permission is hereby granted, free of charge, to any person obtaining a
+*    copy of this software and associated documentation files (the "Software"),
+*    to deal in the Software without restriction, including without limitation
+*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+*    and/or sell copies of the Software, and to permit persons to whom the
+*    Software is furnished to do so, subject to the following conditions:
+*
+*    The above copyright notice and this permission notice shall be included in
+*    all copies or substantial portions of the Software.
+*
+*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+*    DEALINGS IN THE SOFTWARE.
+*
+*****************************************************************************
+*
+*    The GPL License (GPL)
+*
+*    Copyright (C) 2014 - 2019 Vivante Corporation
+*
+*    This program is free software; you can redistribute it and/or
+*    modify it under the terms of the GNU General Public License
+*    as published by the Free Software Foundation; either version 2
+*    of the License, or (at your option) any later version.
+*
+*    This program is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with this program; if not, write to the Free Software Foundation,
+*    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+*    Note: This software is released under dual MIT and GPL licenses. A
+*    recipient may use this file under the terms of either the MIT license or
+*    GPL License. If you wish to use only one license not the other, you can
+*    indicate your decision by deleting one of the above license notices in your
+*    version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_debug_zones_h_
+#define __gc_hal_debug_zones_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+ ************************ Debug Zone Pattern Summary ***************************
+ * A debug zone is an unsigned integer of 32 bit (Bit 31- Bit 0).              *
+ * Bit 31 to 28 defines API, which is 0 for HAL API and has value of 1 - 14    *
+ * for Khronos API. Value 15 (0xF) is reserved for gcdZONE_NONE.               *
+ * Bit 27 to 0 defines subzones of each API. Value 0xFFFFFFF is resevered for  *
+ * gcdZONE_ALL.                                                                *
+ *                                                                             *
+\******************************************************************************/
+
+/* Retrieve API bits 31 to 28 */
+#define gcmZONE_GET_API(zone)             ((zone) >> 28)
+
+/* Retrieve Subzone bits 27 to 0 */
+#define gcmZONE_GET_SUBZONES(zone)        ((zone) << 4)
+
+/******************************************************************************\
+******************************** HAL Zone **************************************
+\******************************************************************************/
+
+#define gcdZONE_API_HAL              ((gctUINT32) 0  << 28)
+
+/******************************************************************************\
+******************************** HAL Subzones **********************************
+\******************************************************************************/
+
+/* Subzones Kernel and User have in common */
+#define gcvZONE_OS              (1 << 0)
+#define gcvZONE_HARDWARE        (1 << 1)
+#define gcvZONE_HEAP            (1 << 2)
+#define gcvZONE_SIGNAL          (1 << 3)
+
+/* Subzones of HAL Kernel */
+#define gcvZONE_KERNEL          (1 << 4)
+#define gcvZONE_VIDMEM          (1 << 5)
+#define gcvZONE_COMMAND         (1 << 6)
+#define gcvZONE_DRIVER          (1 << 7)
+#define gcvZONE_CMODEL          (1 << 8)
+#define gcvZONE_MMU             (1 << 9)
+#define gcvZONE_EVENT           (1 << 10)
+#define gcvZONE_DEVICE          (1 << 11)
+#define gcvZONE_DATABASE        (1 << 12)
+#define gcvZONE_INTERRUPT       (1 << 13)
+#define gcvZONE_POWER           (1 << 14)
+#define gcvZONE_ASYNC_COMMAND   (1 << 15)
+#define gcvZONE_ALLOCATOR       (1 << 16)
+
+/* Subzones of HAL User */
+#define gcdZONE_HAL_API         (1 << 4)
+#define gcdZONE_BUFFER          (1 << 5)
+#define gcdZONE_VGBUFFER        (1 << 6)
+#define gcdZONE_SURFACE         (1 << 7)
+#define gcdZONE_INDEX           (1 << 8)
+#define gcdZONE_STREAM          (1 << 9)
+#define gcdZONE_TEXTURE         (1 << 10)
+#define gcdZONE_2D              (1 << 11)
+#define gcdZONE_3D              (1 << 12)
+#define gcdZONE_COMPILER        (1 << 13)
+#define gcdZONE_MEM             (1 << 14)
+#define gcdZONE_VERTEXARRAY     (1 << 15)
+#define gcdZONE_CL              (1 << 16)
+#define gcdZONE_VG              (1 << 17)
+#define gcdZONE_VX              (1 << 18)
+#define gcdZONE_UTILITY         (1 << 19)
+#define gcdZONE_RECT            (1 << 20)
+#define gcdZONE_BUFOBJ          (1 << 21)
+#define gcdZONE_PROFILER        (1 << 22)
+#define gcdZONE_SHADER          (1 << 23)
+
+
+/******************************************************************************\
+******************************** Khronos API Zones *****************************
+\******************************************************************************/
+
+#define gcdZONE_API_EGL              ((gctUINT32) 1  << 28)
+#define gcdZONE_API_ES11             ((gctUINT32) 2  << 28)
+#define gcdZONE_API_ES30             ((gctUINT32) 3  << 28)
+#define gcdZONE_API_GL40             ((gctUINT32) 4  << 28)
+#define gcdZONE_API_VG3D             ((gctUINT32) 5  << 28)
+#define gcdZONE_API_CL               ((gctUINT32) 6  << 28)
+#define gcdZONE_API_VX               ((gctUINT32) 7  << 28)
+#define gcdZONE_API_VG               ((gctUINT32) 8  << 28)
+
+/******************************************************************************\
+************************* Subzones of Khronos API Zones ************************
+\******************************************************************************/
+
+/* Subzones of EGL API */
+#define gcdZONE_EGL_API              (gcdZONE_API_EGL | (1 << 0))
+#define gcdZONE_EGL_SURFACE          (gcdZONE_API_EGL | (1 << 1))
+#define gcdZONE_EGL_CONTEXT          (gcdZONE_API_EGL | (1 << 2))
+#define gcdZONE_EGL_CONFIG           (gcdZONE_API_EGL | (1 << 3))
+#define gcdZONE_EGL_OS               (gcdZONE_API_EGL | (1 << 4))  /* unused */
+#define gcdZONE_EGL_IMAGE            (gcdZONE_API_EGL | (1 << 5))
+#define gcdZONE_EGL_SWAP             (gcdZONE_API_EGL | (1 << 6))
+#define gcdZONE_EGL_INIT             (gcdZONE_API_EGL | (1 << 7))
+#define gcdZONE_EGL_SYNC             (gcdZONE_API_EGL | (1 << 8))
+#define gcdZONE_EGL_COMPOSE          (gcdZONE_API_EGL | (1 << 9))  /* unused */
+#define gcdZONE_EGL_RENDER_THREAD    (gcdZONE_API_EGL | (1 << 10)) /* unused */
+
+/* Subzones of ES11 API */
+#define gcdZONE_ES11_BUFFER          (gcdZONE_API_ES11 | (1 << 0))
+#define gcdZONE_ES11_CLEAR           (gcdZONE_API_ES11 | (1 << 1))
+#define gcdZONE_ES11_CLIP            (gcdZONE_API_ES11 | (1 << 2))
+#define gcdZONE_ES11_CONTEXT         (gcdZONE_API_ES11 | (1 << 3))
+#define gcdZONE_ES11_DRAW            (gcdZONE_API_ES11 | (1 << 4))
+#define gcdZONE_ES11_ENABLE          (gcdZONE_API_ES11 | (1 << 5))
+#define gcdZONE_ES11_EXTENTION       (gcdZONE_API_ES11 | (1 << 6))
+#define gcdZONE_ES11_FOG             (gcdZONE_API_ES11 | (1 << 7))
+#define gcdZONE_ES11_FRAGMENT        (gcdZONE_API_ES11 | (1 << 8))
+#define gcdZONE_ES11_LIGHT           (gcdZONE_API_ES11 | (1 << 9))
+#define gcdZONE_ES11_MATRIX          (gcdZONE_API_ES11 | (1 << 10))
+#define gcdZONE_ES11_PIXEL           (gcdZONE_API_ES11 | (1 << 11))
+#define gcdZONE_ES11_POLIGON         (gcdZONE_API_ES11 | (1 << 12))
+#define gcdZONE_ES11_LINE            (gcdZONE_API_ES11 | (1 << 13)) /* unused */
+#define gcdZONE_ES11_QUERY           (gcdZONE_API_ES11 | (1 << 14))
+#define gcdZONE_ES11_TEXTURE         (gcdZONE_API_ES11 | (1 << 15))
+#define gcdZONE_ES11_STATES          (gcdZONE_API_ES11 | (1 << 16))
+#define gcdZONE_ES11_STREAM          (gcdZONE_API_ES11 | (1 << 17))
+#define gcdZONE_ES11_VIEWPORT        (gcdZONE_API_ES11 | (1 << 18))
+#define gcdZONE_ES11_SHADER          (gcdZONE_API_ES11 | (1 << 19))
+#define gcdZONE_ES11_HASH            (gcdZONE_API_ES11 | (1 << 20))
+#define gcdZONE_ES11_TRACE           (gcdZONE_API_ES11 | (1 << 21))
+
+/* Subzones of ES30 API */
+#define gcdZONE_ES30_TRACE           (gcdZONE_API_ES30 | (1 << 0))
+#define gcdZONE_ES30_BUFFER          (gcdZONE_API_ES30 | (1 << 1))
+#define gcdZONE_ES30_CLEAR           (gcdZONE_API_ES30 | (1 << 2))
+#define gcdZONE_ES30_CODEC           (gcdZONE_API_ES30 | (1 << 3))
+#define gcdZONE_ES30_CONTEXT         (gcdZONE_API_ES30 | (1 << 4))
+#define gcdZONE_ES30_DEPTH           (gcdZONE_API_ES30 | (1 << 5))
+#define gcdZONE_ES30_DEVICE          (gcdZONE_API_ES30 | (1 << 6))
+#define gcdZONE_ES30_DRAW            (gcdZONE_API_ES30 | (1 << 7))
+#define gcdZONE_ES30_FBO             (gcdZONE_API_ES30 | (1 << 8))
+#define gcdZONE_ES30_PIXEL           (gcdZONE_API_ES30 | (1 << 9))
+#define gcdZONE_ES30_SHADER          (gcdZONE_API_ES30 | (1 << 10))
+#define gcdZONE_ES30_STATE           (gcdZONE_API_ES30 | (1 << 11))
+#define gcdZONE_ES30_TEXTURE         (gcdZONE_API_ES30 | (1 << 12))
+#define gcdZONE_ES30_UTILS           (gcdZONE_API_ES30 | (1 << 13))
+#define gcdZONE_ES30_PROFILER        (gcdZONE_API_ES30 | (1 << 14))
+#define gcdZONE_ES30_CORE            (gcdZONE_API_ES30 | (1 << 15))
+
+/* Subzones of GL40 API */
+#define gcdZONE_GL40_TRACE           (gcdZONE_API_GL40 | (1 << 0))
+#define gcdZONE_GL40_BUFFER          (gcdZONE_API_GL40 | (1 << 1))
+#define gcdZONE_GL40_CLEAR           (gcdZONE_API_GL40 | (1 << 2))  /* unused */
+#define gcdZONE_GL40_CODEC           (gcdZONE_API_GL40 | (1 << 3))
+#define gcdZONE_GL40_CONTEXT         (gcdZONE_API_GL40 | (1 << 4))
+#define gcdZONE_GL40_DEPTH           (gcdZONE_API_GL40 | (1 << 5))
+#define gcdZONE_GL40_DEVICE          (gcdZONE_API_GL40 | (1 << 6))
+#define gcdZONE_GL40_DRAW            (gcdZONE_API_GL40 | (1 << 7))
+#define gcdZONE_GL40_FBO             (gcdZONE_API_GL40 | (1 << 8))
+#define gcdZONE_GL40_PIXEL           (gcdZONE_API_GL40 | (1 << 9))
+#define gcdZONE_GL40_SHADER          (gcdZONE_API_GL40 | (1 << 10))
+#define gcdZONE_GL40_STATE           (gcdZONE_API_GL40 | (1 << 11))
+#define gcdZONE_GL40_TEXTURE         (gcdZONE_API_GL40 | (1 << 12))
+#define gcdZONE_GL40_UTILS           (gcdZONE_API_GL40 | (1 << 13))
+#define gcdZONE_GL40_PROFILER        (gcdZONE_API_GL40 | (1 << 14))
+#define gcdZONE_GL40_CORE            (gcdZONE_API_GL40 | (1 << 15))
+#define gcdZONE_GL40_FIXVERTEX       (gcdZONE_API_GL40 | (1 << 16))
+#define gcdZONE_GL40_FIXFRAG         (gcdZONE_API_GL40 | (1 << 17))
+#define gcdZONE_GL40_HASH            (gcdZONE_API_GL40 | (1 << 18))
+
+/* Subzones of VG3D API  */
+#define gcdZONE_VG3D_CONTEXT           (gcdZONE_API_VG3D | (1 << 0))
+#define gcdZONE_VG3D_DUMP              (gcdZONE_API_VG3D | (1 << 1))
+#define gcdZONE_VG3D_EGL               (gcdZONE_API_VG3D | (1 << 2))
+#define gcdZONE_VG3D_FONT              (gcdZONE_API_VG3D | (1 << 3))
+#define gcdZONE_VG3D_HARDWARE          (gcdZONE_API_VG3D | (1 << 4))
+#define gcdZONE_VG3D_IMAGE             (gcdZONE_API_VG3D | (1 << 5))
+#define gcdZONE_VG3D_MASK              (gcdZONE_API_VG3D | (1 << 6))
+#define gcdZONE_VG3D_MATRIX            (gcdZONE_API_VG3D | (1 << 7))
+#define gcdZONE_VG3D_OBJECT            (gcdZONE_API_VG3D | (1 << 8))
+#define gcdZONE_VG3D_PAINT             (gcdZONE_API_VG3D | (1 << 9))
+#define gcdZONE_VG3D_PATH              (gcdZONE_API_VG3D | (1 << 10))
+#define gcdZONE_VG3D_PROFILER          (gcdZONE_API_VG3D | (1 << 11))
+#define gcdZONE_VG3D_SCANLINE          (gcdZONE_API_VG3D | (1 << 12))
+#define gcdZONE_VG3D_SHADER            (gcdZONE_API_VG3D | (1 << 13))
+#define gcdZONE_VG3D_TESSELLATOR       (gcdZONE_API_VG3D | (1 << 14))
+#define gcdZONE_VG3D_VGU               (gcdZONE_API_VG3D | (1 << 15))
+
+/* Subzones of VG11 API  */
+#define gcdZONE_VG_ARC               (gcdZONE_API_VG | (1 << 0))
+#define gcdZONE_VG_CONTEXT           (gcdZONE_API_VG | (1 << 1))
+#define gcdZONE_VG_DEBUG             (gcdZONE_API_VG | (1 << 2))
+#define gcdZONE_VG_FILTER            (gcdZONE_API_VG | (1 << 3))
+#define gcdZONE_VG_FORMAT            (gcdZONE_API_VG | (1 << 4))
+#define gcdZONE_VG_IMAGE             (gcdZONE_API_VG | (1 << 5))
+#define gcdZONE_VG_MAIN              (gcdZONE_API_VG | (1 << 6))
+#define gcdZONE_VG_MASK              (gcdZONE_API_VG | (1 << 7))
+#define gcdZONE_VG_MATRIX            (gcdZONE_API_VG | (1 << 8))
+#define gcdZONE_VG_MEMORYMGR         (gcdZONE_API_VG | (1 << 9))
+#define gcdZONE_VG_OBJECT            (gcdZONE_API_VG | (1 << 10))
+#define gcdZONE_VG_PAINT             (gcdZONE_API_VG | (1 << 11))
+#define gcdZONE_VG_PATH              (gcdZONE_API_VG | (1 << 12))
+#define gcdZONE_VG_STATE             (gcdZONE_API_VG | (1 << 13))
+#define gcdZONE_VG_STROKE            (gcdZONE_API_VG | (1 << 14))
+#define gcdZONE_VG_TEXT              (gcdZONE_API_VG | (1 << 15))
+#define gcdZONE_VG_VGU               (gcdZONE_API_VG | (1 << 16))
+
+/* Subzones of CL API  */
+#define gcdZONE_CL_COMMAND           (gcdZONE_API_CL | (1 << 0))
+#define gcdZONE_CL_CONTEXT           (gcdZONE_API_CL | (1 << 1))
+#define gcdZONE_CL_DEVICE            (gcdZONE_API_CL | (1 << 2))
+#define gcdZONE_CL_ENQUEUE           (gcdZONE_API_CL | (1 << 3))
+#define gcdZONE_CL_EVENT             (gcdZONE_API_CL | (1 << 4))
+#define gcdZONE_CL_EXT               (gcdZONE_API_CL | (1 << 5))
+#define gcdZONE_CL_GL                (gcdZONE_API_CL | (1 << 6))
+#define gcdZONE_CL_KERNEL            (gcdZONE_API_CL | (1 << 7))
+#define gcdZONE_CL_MEM               (gcdZONE_API_CL | (1 << 8))
+#define gcdZONE_CL_PLATFORM          (gcdZONE_API_CL | (1 << 9))
+#define gcdZONE_CL_PROFILER          (gcdZONE_API_CL | (1 << 10))
+#define gcdZONE_CL_PROGRAM           (gcdZONE_API_CL | (1 << 11))
+#define gcdZONE_CL_SAMPLER           (gcdZONE_API_CL | (1 << 12))
+
+/* Subzones of VX API  */
+#define gcdZONE_VX_ARRAY             (gcdZONE_API_VX | (1 << 0))
+#define gcdZONE_VX_BINARY            (gcdZONE_API_VX | (1 << 1))
+#define gcdZONE_VX_CONTEXT           (gcdZONE_API_VX | (1 << 2))
+#define gcdZONE_VX_CONV              (gcdZONE_API_VX | (1 << 3))
+#define gcdZONE_VX_DELAY             (gcdZONE_API_VX | (1 << 4))
+#define gcdZONE_VX_DIST              (gcdZONE_API_VX | (1 << 5))
+#define gcdZONE_VX_GPULAYER          (gcdZONE_API_VX | (1 << 6))
+#define gcdZONE_VX_GRAPH             (gcdZONE_API_VX | (1 << 7))
+#define gcdZONE_VX_IMAGE             (gcdZONE_API_VX | (1 << 8))
+#define gcdZONE_VX_INTERFACE         (gcdZONE_API_VX | (1 << 9))
+#define gcdZONE_VX_KERNEL            (gcdZONE_API_VX | (1 << 10))
+#define gcdZONE_VX_LAYER             (gcdZONE_API_VX | (1 << 11))
+#define gcdZONE_VX_LUT               (gcdZONE_API_VX | (1 << 12))
+#define gcdZONE_VX_MATRIX            (gcdZONE_API_VX | (1 << 13))
+#define gcdZONE_VX_MEMORY            (gcdZONE_API_VX | (1 << 14))
+#define gcdZONE_VX_METAFMT           (gcdZONE_API_VX | (1 << 15))
+#define gcdZONE_VX_NODE              (gcdZONE_API_VX | (1 << 16))
+#define gcdZONE_VX_OBJARRAY          (gcdZONE_API_VX | (1 << 17))
+#define gcdZONE_VX_PARAM             (gcdZONE_API_VX | (1 << 18))
+#define gcdZONE_VX_PROGRAM           (gcdZONE_API_VX | (1 << 19))
+#define gcdZONE_VX_PYRAMID           (gcdZONE_API_VX | (1 << 20))
+#define gcdZONE_VX_REF               (gcdZONE_API_VX | (1 << 21))
+#define gcdZONE_VX_REMAP             (gcdZONE_API_VX | (1 << 22))
+#define gcdZONE_VX_SCALAR            (gcdZONE_API_VX | (1 << 23))
+#define gcdZONE_VX_TARGET            (gcdZONE_API_VX | (1 << 24))
+#define gcdZONE_VX_TENSOR            (gcdZONE_API_VX | (1 << 25))
+#define gcdZONE_VX_THRESHOLD         (gcdZONE_API_VX | (1 << 26))
+#define gcdZONE_VX_OTHERS            (gcdZONE_API_VX | (1 << 27))
+
+/******************************************************************************\
+******************************** Utility Zones *********************************
+\******************************************************************************/
+
+/* Value for Disabling All Subzones */
+#define gcdZONE_NONE                 0xF0000000
+
+/* Value for Enabling All Subzones */
+#define gcdZONE_ALL                  0x0FFFFFFF
+
+
+/******************************************************************************\
+*********************************** END ****************************************
+\******************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_debug_zones_h_ */
+
+
index 4ac050a31ee69d596723b69a32f5f4c61d1197f0..ba1581746a206c835892ab8f8b11ab621d0db42e 100644 (file)
@@ -134,6 +134,7 @@ typedef enum _gceHAL_COMMAND_CODES
     gcvHAL_READ_PROFILER_REGISTER_SETTING,
     gcvHAL_READ_ALL_PROFILE_REGISTERS_PART1,
     gcvHAL_READ_ALL_PROFILE_REGISTERS_PART2,
+
     /* Query process database info when debug trace and proflie. */
     gcvHAL_DATABASE,
 
@@ -146,7 +147,6 @@ typedef enum _gceHAL_COMMAND_CODES
     /*************** Common end ***************/
 
     /*************** GPU only ***************/
-
     /* Register operations, 2D only. */
     gcvHAL_READ_REGISTER,
     gcvHAL_WRITE_REGISTER,
@@ -158,6 +158,9 @@ typedef enum _gceHAL_COMMAND_CODES
     /* Read frame database, 3D only. */
     gcvHAL_GET_FRAME_INFO,
 
+    /* Set video memory meta data. */
+    gcvHAL_SET_VIDEO_MEMORY_METADATA,
+
     /* Query command buffer, VG only. */
     gcvHAL_QUERY_COMMAND_BUFFER,
 
@@ -178,6 +181,8 @@ typedef enum _gceHAL_COMMAND_CODES
     gcvHAL_NAME_VIDEO_MEMORY,
     gcvHAL_IMPORT_VIDEO_MEMORY,
 
+    /* Mutex Operation. */
+    gcvHAL_DEVICE_MUTEX,
     /*************** GPU only end ***************/
 
     /*************** DEC only ***************/
@@ -201,6 +206,7 @@ typedef enum _gceHAL_COMMAND_CODES
 
     /* Vsimulator only. */
     gcvHAL_UPDATE_DEBUG_CALLBACK,
+    gcvHAL_CONFIG_CTX_FRAMEWORK,
 
     /* Non paged memory management backup compatibility, windows, qnx. */
     gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
@@ -215,7 +221,7 @@ typedef enum _gceHAL_COMMAND_CODES
     gcvHAL_SET_IDLE,
     gcvHAL_RESET,
 
-    /* Command commit done. */
+    /* Command commit done, kernel event only. */
     gcvHAL_COMMIT_DONE,
 
     /* Get video memory file description. */
@@ -314,6 +320,14 @@ typedef struct _gcsHAL_QUERY_VIDEO_MEMORY
 }
 gcsHAL_QUERY_VIDEO_MEMORY;
 
+enum
+{
+    /* GPU can't issue more that 32bit physical address */
+    gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS = 1 << 0,
+
+    gcvPLATFORM_FLAG_IMX_MM           = 1 << 1,
+};
+
 /* gcvHAL_QUERY_CHIP_IDENTITY */
 typedef struct _gcsHAL_QUERY_CHIP_IDENTITY * gcsHAL_QUERY_CHIP_IDENTITY_PTR;
 typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
@@ -389,8 +403,10 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
     gctUINT32                   customerID;
 
     /* CPU view physical address and size of SRAMs. */
-    gctUINT64                   sRAMBases[gcvSRAM_COUNT];
-    gctUINT32                   sRAMSizes[gcvSRAM_COUNT];
+    gctUINT64                   sRAMBases[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMSizes[gcvSRAM_INTER_COUNT];
+
+    gctUINT64                   platformFlagBits;
 }
 gcsHAL_QUERY_CHIP_IDENTITY;
 
@@ -411,15 +427,22 @@ typedef struct _gcsHAL_QUERY_CHIP_OPTIONS
     gctUINT32                   uscAttribCacheRatio;
     gctUINT32                   userClusterMask;
 
-    /* GPU/VIP virtual address of SRAMs. */
-    gctUINT32                   sRAMBaseAddresses[gcvSRAM_COUNT];
-    /* SRAMs size. */
-    gctUINT32                   sRAMSizes[gcvSRAM_COUNT];
-    /* GPU/VIP view physical address of SRAMs. */
-    gctPHYS_ADDR_T              sRAMPhysicalBases[gcvSRAM_COUNT];
+    /* Internal SRAM. */
+    gctUINT32                   sRAMGPUVirtAddrs[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMSizes[gcvSRAM_INTER_COUNT];
+    gctUINT32                   sRAMCount;
 
-    gceSECURE_MODE              secureMode;
+    /* External SRAM. */
+    gctPHYS_ADDR_T              extSRAMCPUPhysAddrs[gcvSRAM_EXT_COUNT];
+    gctPHYS_ADDR_T              extSRAMGPUPhysAddrs[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMGPUVirtAddrs[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMGPUPhysNames[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMSizes[gcvSRAM_EXT_COUNT];
+    gctUINT32                   extSRAMCount;
 
+    gceSECURE_MODE              secureMode;
+    gctBOOL                     enableNNTPParallel;
+    gctUINT                     enableSwtilingPhase1;
 }
 gcsHAL_QUERY_CHIP_OPTIONS;
 
@@ -484,6 +507,11 @@ typedef struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
     /* Memory pool to allocate from. */
     IN OUT gctUINT32            pool;
 
+    /* Internal SRAM index. */
+    IN gctINT32                 sRAMIndex;
+    /* External SRAM index. */
+    IN gctINT32                 extSRAMIndex;
+
     /* Allocated video memory. */
     OUT gctUINT32               node;
 }
@@ -766,6 +794,8 @@ typedef struct _gcsHAL_COMMIT
 
     gctBOOL                     shared;
 
+    gctBOOL                     contextSwitched;
+
     /* Commit stamp of this commit. */
     OUT gctUINT64               commitStamp;
 }
@@ -1128,6 +1158,23 @@ typedef struct _gcsHAL_GET_GRAPHIC_BUFFER_FD
 }
 gcsHAL_GET_GRAPHIC_BUFFER_FD;
 
+typedef struct _gcsHAL_VIDEO_MEMORY_METADATA
+{
+    /* Allocated video memory. */
+    IN gctUINT32            node;
+
+    IN gctUINT32            readback;
+
+    INOUT gctINT32          ts_fd;
+    INOUT gctUINT32         fc_enabled;
+    INOUT gctUINT32         fc_value;
+    INOUT gctUINT32         fc_value_upper;
+
+    INOUT gctUINT32         compressed;
+    INOUT gctUINT32         compress_format;
+}
+gcsHAL_VIDEO_MEMORY_METADATA;
+
 /* gcvHAL_GET_VIDEO_MEMORY_FD. */
 typedef struct _gcsHAL_GET_VIDEO_MEMORY_FD
 {
@@ -1152,6 +1199,14 @@ typedef struct _gcsHAL_WAIT_FENCE
 }
 gcsHAL_WAIT_FENCE;
 
+/* gcvHAL_DEVICE_MUTEX: */
+typedef struct _gcsHAL_DEVICE_MUTEX
+{
+    /* Lock or Release device mutex. */
+    gctBOOL                     isMutexLocked;
+}
+gcsHAL_DEVICE_MUTEX;
+
 
 #if gcdDEC_ENABLE_AHB
 /* gcvHAL_DEC300_READ. */
@@ -1219,6 +1274,9 @@ typedef struct _gcsHAL_INTERFACE
     /* Ignore information from TSL when doing IO control */
     gctBOOL                     ignoreTLS;
 
+    /* The mutext already acquired */
+    IN gctBOOL                  commitMutex;
+
     /* Union of command structures. */
     union _u
     {
@@ -1303,12 +1361,16 @@ typedef struct _gcsHAL_INTERFACE
         gcsHAL_WAIT_NATIVE_FENCE            WaitNativeFence;
         gcsHAL_SHBUF                        ShBuf;
         gcsHAL_GET_GRAPHIC_BUFFER_FD        GetGraphicBufferFd;
+        gcsHAL_VIDEO_MEMORY_METADATA        SetVidMemMetadata;
         gcsHAL_GET_VIDEO_MEMORY_FD          GetVideoMemoryFd;
 
         gcsHAL_DESTROY_MMU                  DestroyMmu;
 
         gcsHAL_WAIT_FENCE                   WaitFence;
 
+        /* gcvHAL_DEVICE_MUTEX: */
+        gcsHAL_DEVICE_MUTEX                 DeviceMutex;
+
 
 #if gcdDEC_ENABLE_AHB
         gcsHAL_DEC300_READ                  DEC300Read;
index 1355bcd25b1601ce10c58a4ded1abd01cc4a0a3a..6e0bb5dec3460bc2f3b89ce0aa1c0e070f66f990 100644 (file)
@@ -56,9 +56,7 @@
 #ifndef __VIVNATE_DRM_H__
 #define __VIVNATE_DRM_H__
 
-#if !defined(__KERNEL__)
 #include <drm.h>
-#endif
 
 #if defined(__cplusplus)
 extern "C" {
index e9214ab53f4946fb55139316239388b851b2c9fa..69d3699d3c5ddcec998f99e20d1041442a8e2691 100644 (file)
@@ -124,13 +124,14 @@ typedef struct _gcoBUFOBJ *             gcoBUFOBJ;
 
 typedef enum _gcePROGRAM_STAGE
 {
-    gcvPROGRAM_STAGE_VERTEX   = 0x0,
-    gcvPROGRAM_STAGE_TCS      = 0x1,
-    gcvPROGRAM_STAGE_TES      = 0x2,
-    gcvPROGRAM_STAGE_GEOMETRY = 0x3,
-    gcvPROGRAM_STAGE_FRAGMENT = 0x4,
-    gcvPROGRAM_STAGE_COMPUTE  = 0x5,
-    gcvPROGRAM_STAGE_OPENCL   = 0x6,
+    gcvPROGRAM_STAGE_VERTEX         = 0x0,
+    gcvPROGRAM_STAGE_TCS            = 0x1,
+    gcvPROGRAM_STAGE_TES            = 0x2,
+    gcvPROGRAM_STAGE_GEOMETRY       = 0x3,
+    gcvPROGRAM_STAGE_FRAGMENT       = 0x4,
+    gcvPROGRAM_STAGE_GRAPHICS_COUNT = 0x5,
+    gcvPROGRAM_STAGE_COMPUTE        = 0x5,
+    gcvPROGRAM_STAGE_OPENCL         = 0x6,
     gcvPROGRAM_STAGE_LAST
 }
 gcePROGRAM_STAGE;
@@ -240,6 +241,7 @@ typedef struct _gcsSURF_BLIT_ARGS
     gcsRECT     scissor;
     gctUINT     flags;
     gctUINT     srcNumSlice, dstNumSlice;
+    gctBOOL     needDecode;
 }
 gcsSURF_BLIT_ARGS;
 
@@ -318,6 +320,7 @@ typedef enum _gceSPLIT_DRAW_TYPE
     gcvSPLIT_DRAW_1,
     gcvSPLIT_DRAW_2,
     gcvSPLIT_DRAW_3,
+    gcvSPLIT_DRAW_4,
     gcvSPLIT_DRAW_XFB,
     gcvSPLIT_DRAW_INDEX_FETCH,
     gcvSPLIT_DRAW_TCS,
@@ -677,7 +680,7 @@ gceSTATUS
 gcoINDEX_GetIndexRange(
     IN gcoINDEX Index,
     IN gceINDEX_TYPE Type,
-    IN gctUINT32 Offset,
+    IN gctSIZE_T Offset,
     IN gctUINT32 Count,
     OUT gctUINT32 * MinimumIndex,
     OUT gctUINT32 * MaximumIndex
@@ -1644,6 +1647,7 @@ typedef struct _gcsTHREAD_WALKER_INFO
     gctBOOL     indirect;
     gctUINT32   groupNumberUniformIdx;
     gctUINT32   baseAddress;
+    gctBOOL     bDual16;
 }
 gcsTHREAD_WALKER_INFO;
 
@@ -2188,6 +2192,7 @@ gcoTEXTURE_AddMipMap(
     IN gctSIZE_T Depth,
     IN gctUINT Faces,
     IN gcePOOL Pool,
+    IN gctBOOL Filterable,
     OUT gcoSURF * Surface
     );
 
@@ -2204,6 +2209,7 @@ gcoTEXTURE_AddMipMapEx(
     IN gcePOOL Pool,
     IN gctUINT32 Samples,
     IN gctBOOL Protected,
+    IN gctBOOL Filterable,
     OUT gcoSURF * Surface
     );
 
@@ -2377,7 +2383,8 @@ gceSTATUS
 gcoTEXTURE_GenerateMipMap(
     IN gcoTEXTURE Texture,
     IN gctINT   BaseLevel,
-    IN gctINT   MaxLevel
+    IN gctINT   MaxLevel,
+    IN gctBOOL  sRGBDecode
     );
 
 /******************************************************************************\
@@ -2705,6 +2712,7 @@ typedef struct _gcsVERTEXARRAY_INDEX_INFO
     gctSIZE_T        count;
     gceINDEX_TYPE    indexType;
     gctPOINTER       indexMemory;
+    gctUINT          restartElement;
 
     union _gcsVERTEXARRAY_INDEX_INFO_UNION
     {
@@ -2885,8 +2893,9 @@ gceSTATUS
 gcoBUFOBJ_IndexBind (
     IN gcoBUFOBJ Index,
     IN gceINDEX_TYPE Type,
-    IN gctUINT32 Offset,
-    IN gctSIZE_T Count
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Count,
+    IN gctUINT   RestartElement
     );
 
 /* Find min and max index for the index buffer */
@@ -2894,7 +2903,7 @@ gceSTATUS
 gcoBUFOBJ_IndexGetRange(
     IN gcoBUFOBJ Index,
     IN gceINDEX_TYPE Type,
-    IN gctUINT32 Offset,
+    IN gctSIZE_T Offset,
     IN gctUINT32 Count,
     OUT gctUINT32 * MinimumIndex,
     OUT gctUINT32 * MaximumIndex
index e7f57efc8e224a75916cab8b320413163610eb4f..5a1655a69cefc9b8702f023d52ea1fafbbed0c56 100644 (file)
@@ -99,6 +99,7 @@ typedef enum _gceCHIPMODEL
     gcv6400 = 0x6400,
     gcv7000 = 0x7000,
     gcv7400 = 0x7400,
+    gcv8000 = 0x8000,
 }
 gceCHIPMODEL;
 
@@ -191,7 +192,7 @@ typedef enum _gceFEATURE
     gcvFEATURE_SUPERTILED_TEXTURE,
     gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
     gcvFEATURE_RS_YUV_TARGET,
-    gcvFEATURE_2D_FC_SOURCE,/* For tilestatus compression feature*/
+    gcvFEATURE_2D_FC_SOURCE, /* For tilestatus compression feature*/
     gcvFEATURE_2D_CC_NOAA_SOURCE,
     gcvFEATURE_PE_DITHER_FIX,
     gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
@@ -497,7 +498,6 @@ typedef enum _gceFEATURE
     gcvFEATURE_SH_HALF_DEPENDENCY_FIX,
     gcvFEATURE_FE_BASEINSTANCE,
     gcvFEATURE_FE_COMPUREINDIRECT_SKIP_UNIFORM,
-    gcvFEATURE_FE_DRAW_DIRECT,
     gcvFEATURE_SH_CLOCK_GATE_FIX,
     gcvFEATURE_GPIPE_CLOCK_GATE_FIX,
     gcvFEATURE_TP_ENGINE,
@@ -533,6 +533,7 @@ typedef enum _gceFEATURE
     gcvFEATURE_NN_BRICK_MODE,
     gcvFEATURE_NN_BORDER_MODE,
     gcvFEATURE_NN_FP16_ALU,
+    gcvFEATURE_NN_BF16_ALU,
     gcvFEATURE_NN_INT16_ALU,
     gcvFEATURE_NN_ZDP3,
     gcvFEATURE_NN_ZDP6,
@@ -552,7 +553,6 @@ typedef enum _gceFEATURE
     gcvFEATURE_NN_STRIDE_SUPPORT,
     gcvFEATURE_NN_XYDP6,
     gcvFEATURE_NN_XYDP0,
-    gcvFEATURE_IMAGE_LS_NO_FULLMASK_FIX,
     gcvFEATURE_TP_REORDER_FIX,
     gcvFEATURE_NN_CONV1x1_PERF_FIX,
     gcvFEATURE_NN_CACHELINE_MODE_PERF_FIX,
@@ -567,15 +567,40 @@ typedef enum _gceFEATURE
     gcvFEATURE_NN_ASYNC_COPY_PERF_FIX,
     gcvFEATURE_OCB_COUNTER,
     gcvFEATURE_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX,
+    gcvFEATURE_NN_FULLCACHE_KERNEL_INTERLEAVE_FIX,
+    gcvFEATURE_DR_JD_DIFF_CONDITION_FOR_CACHELINE_MODE_PRE_FIX,
+    gcvFEATURE_USC_BOTTLENECK_FIX,
+    gcvFEATURE_OCB_REMAP_PHYSICAL_ADDRESS,
+    gcvFEATURE_NN_SLICE_PADDING_TO_64BYTE_ALIGN,
+    gcvFEATURE_NN_DW_1x1_CONV_MERGE,
+    gcvFEATURE_TP_REORDER_LAYER_SUSPEND_FIX,
+    gcvFEATURE_KERNEL_VIP_SRAM_READ_BW_LIMITATION_FIX,
+    gcvFEATURE_IMG_POP_PIPELINE_PAUSE_FIX,
+    gcvFEATURE_NN_SLOW_OUTPUT,
+    gcvFEATURE_NO_NARROW_POST_PROCESS_PIPE,
+    gcvFEATURE_TP_NN_PROBE,
+    gcvFEATURE_TP_23BITS_POST_MULTIPLIER,
+    gcvFEATURE_NN_TRANSPOSE,
+
+    gcvFEATURE_IMAGE_LS_NO_FULLMASK_FIX,
+    gcvFEATURE_BLT_YUV_OUTPUT,
+    gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX,
+    gcvFEATURE_SH_ROBUSTNESS_FIX,
     gcvFEATURE_USC_ATOMIC_FIX2,
+    gcvFEATURE_MULTIVIEW_RENDER,
+    gcvFEATURE_FE_DRAW_DIRECT,
+    gcvFEATURE_TX_VKBORDER_MODE,
+    gcvFEATURE_TX_UNNORMALIZED_COORD,
     gcvFEATURE_VG_IMAGE_16K,
     gcvFEATURE_MULTICORE_CONFIG,
+    gcvFEATURE_PA_LINECLIP_FIX,
     gcvFEATURE_NN_ENGINE,
     gcvFEATURE_NN_ASYNC_COPY_MERGE_FIX,
     gcvFEATURE_NN_CONVOUT_FIFO_DEPTH_FIX,
     gcvFEATURE_NN_SMALLBATCH_PHASE1,
     gcvFEATURE_TP_SMALLBATCH_PHASE1,
     gcvFEATURE_VIP_SCALER,
+    gcvFEATURE_TX_8bit_UVFrac_ROUNDING_FIX,
     gcvFEATURE_NN_REQ_SLOWARBITRATION_FIX,
     gcvFEATUER_IMAGE_PARTIAL_CACHE,
     gcvFEATURE_FULLCACHE_KERNELHEAD_FIX,
@@ -592,7 +617,15 @@ typedef enum _gceFEATURE
     gcvFEATURE_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX,
     gcvFEATURE_XY_OFFSET_LIMITATION_FIX,
     gcvFEATURE_USC_INVALIDATE_CACHE_LINE_FIX,
+    gcvFEATURE_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX,
+    gcvFEATURE_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX,
+    gcvFEATURE_NN_PER_CHANNEL_POST_MULTIPLY,
+    gcvFEATURE_NN_NO_Z_LOCATION_OFFSET,
+    gcvFEATURE_NN_PRELU,
+    gcvFEATURE_NN_KERNEL_SIZE_WASTE_IN_PARTIAL_MODE_FIX,
+    gcvFEATURE_INCORRECT_WR_REQ_TO_USC_BETWEEN_REORDER_AND_NORMAL_LAYER_FIX,
     gcvFEATURE_VIP_DEC400,
+    gcvFEATURE_MAX_POINTSIZE_CLAMP,
     gcvFEATURE_2D_FAST_CLEAR, /* For tilestatus Fast Clear feature*/
 
     /* Insert features above this comment only. */
@@ -629,6 +662,7 @@ typedef enum _gceOPTION
     gcvOPTION_FBO_PREFER_MEM = 54,
     gcvOPTION_GPU_TEX_UPLOAD = 55,
     gcvOPTION_GPU_BUFOBJ_UPLOAD = 56,
+    gcvOPTION_NO_Y_INVERT = 60,
 
     /* OCL option */
     gcvOPTION_OCL_ASYNC_BLT = 200,
@@ -643,8 +677,8 @@ typedef enum _gceOPTION
     gcvOPTION_OVX_ENABLE_NN_ZDP6,
     gcvOPTION_OVX_ENABLE_NN_STRIDE,
     gcvOPTION_OVX_USE_MULTI_DEVICES,
+    gcvOPTION_OVX_ENABLE_NN_DDR_BURST_SIZE_256B,
 #endif
-
     /* Insert option above this comment only */
     gcvOPTION_COUNT                     /* Not a OPTION*/
 }
@@ -757,6 +791,7 @@ typedef enum _gceSURF_TYPE
     gcvSURF_NO_HZ                   = 0x100000,
     gcvSURF_3D                      = 0x200000, /* It's 3d surface */
     gcvSURF_DMABUF_EXPORTABLE       = 0x400000, /* master node can be exported as dma-buf fd */
+    gcvSURF_CACHE_MODE_128          = 0x800000,
 
     gcvSURF_TEXTURE_LINEAR               = gcvSURF_TEXTURE
                                          | gcvSURF_LINEAR,
@@ -1014,6 +1049,7 @@ typedef enum _gceSURF_FORMAT
     gcvSURF_L16,
     gcvSURF_L32,
     gcvSURF_L1,
+    gcvSURF_L8_RAW,
 
     /* Alpha/Luminance formats. */
     gcvSURF_A4L4                = 900,
@@ -1023,6 +1059,10 @@ typedef enum _gceSURF_FORMAT
     gcvSURF_A12L12,
     gcvSURF_A16L16,
 
+    gcvSURF_A8L8_1_A8R8G8B8,
+
+    gcvSURF_A8L8_RAW,
+
     /* Bump formats. */
     gcvSURF_L6V5U5              = 1000,
     gcvSURF_V8U8,
@@ -1671,9 +1711,10 @@ gceFILTER_PASS_TYPE;
 /* Endian hints. */
 typedef enum _gceENDIAN_HINT
 {
-    gcvENDIAN_NO_SWAP = 0,
-    gcvENDIAN_SWAP_WORD,
-    gcvENDIAN_SWAP_DWORD
+    gcvENDIAN_NO_SWAP    = 0,
+    gcvENDIAN_SWAP_WORD  = 1,
+    gcvENDIAN_SWAP_DWORD = 2,
+    gcvENDIAN_SWAP_QWORD = 3,
 }
 gceENDIAN_HINT;
 
@@ -2176,14 +2217,23 @@ typedef enum _gceMCFE_CHANNEL_TYPE
 }
 gceMCFE_CHANNEL_TYPE;
 
-typedef enum _gceSRAM
+typedef enum _gceSRAM_INTERNAL
 {
-    gcvSRAM_INTERNAL  = 0,
-    gcvSRAM_EXTERNAL0 = 1,
-    gcvSRAM_EXTERNAL1 = 2,
-    gcvSRAM_COUNT
+    gcvSRAM_INTERNAL0 = 0,
+    gcvSRAM_INTERNAL1,
+
+    gcvSRAM_INTER_COUNT
 }
-gceSRAM;
+gceSRAM_INTERNAL;
+
+typedef enum _gceSRAM_EXTERNAL
+{
+    gcvSRAM_EXTERNAL0 = 0,
+    gcvSRAM_EXTERNAL1,
+
+    gcvSRAM_EXT_COUNT
+}
+gceSRAM_EXTERNAL;
 
 typedef enum _gceFLATMAP_FLAG
 {
@@ -2192,6 +2242,22 @@ typedef enum _gceFLATMAP_FLAG
 }
 gceFLATMAP_FLAG;
 
+typedef enum _gcePAGE_TYPE
+{
+    gcvPAGE_TYPE_1M,
+    gcvPAGE_TYPE_4K,
+}
+gcePAGE_TYPE;
+
+typedef enum _gceAREA_TYPE
+{
+    gcvAREA_TYPE_UNKNOWN = 0,
+    gcvAREA_TYPE_FLATMAP,
+    gcvAREA_TYPE_1M,
+    gcvAREA_TYPE_4K,
+}
+gceAREA_TYPE;
+
 /* Video memory alloation type. */
 typedef enum _gceVIDMEM_TYPE
 {
@@ -2251,6 +2317,12 @@ gceVIDMEM_TYPE;
 /* Import linux reserved memory. */
 #define gcvALLOC_FLAG_LINUX_RESERVED_MEM    0x00008000
 
+/* 1M pages unit allocation. */
+#define gcvALLOC_FLAG_1M_PAGES              0x00010000
+
+/* Non 1M pages unit allocation. */
+#define gcvALLOC_FLAG_4K_PAGES              0x00020000
+
 /* Real allocation happens when GPU page fault. */
 #define gcvALLOC_FLAG_ALLOC_ON_FAULT        0x01000000
 /* Alloc with memory limit. */
index 32d2a23073c0718f4c982a8c370a78febcc11c13..83a04ac0b2bce8f3d98739b1682196897b195b32 100644 (file)
@@ -250,13 +250,6 @@ struct _gcoCMDBUF
     gctUINT64                   lastReserve;
     gctUINT32                   lastOffset;
 
-#if gcdSECURE_USER
-    /* Hint array for the current command buffer. */
-    gctUINT                     hintArraySize;
-    gctUINT64                   hintArray;
-    gctUINT64                   hintArrayTail;
-#endif
-
     /* Last load state command location and hardware address. */
     gctUINT64                   lastLoadStatePtr;
     gctUINT32                   lastLoadStateAddress;
diff --git a/drivers/amlogic/npu/kernel/inc/gc_hal_metadata.h b/drivers/amlogic/npu/kernel/inc/gc_hal_metadata.h
new file mode 100644 (file)
index 0000000..c59b03e
--- /dev/null
@@ -0,0 +1,121 @@
+/****************************************************************************
+*
+*    The MIT License (MIT)
+*
+*    Copyright (c) 2014 - 2019 Vivante Corporation
+*
+*    Permission is hereby granted, free of charge, to any person obtaining a
+*    copy of this software and associated documentation files (the "Software"),
+*    to deal in the Software without restriction, including without limitation
+*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+*    and/or sell copies of the Software, and to permit persons to whom the
+*    Software is furnished to do so, subject to the following conditions:
+*
+*    The above copyright notice and this permission notice shall be included in
+*    all copies or substantial portions of the Software.
+*
+*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+*    DEALINGS IN THE SOFTWARE.
+*
+*****************************************************************************
+*
+*    The GPL License (GPL)
+*
+*    Copyright (C) 2014 - 2019 Vivante Corporation
+*
+*    This program is free software; you can redistribute it and/or
+*    modify it under the terms of the GNU General Public License
+*    as published by the Free Software Foundation; either version 2
+*    of the License, or (at your option) any later version.
+*
+*    This program is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with this program; if not, write to the Free Software Foundation,
+*    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+*    Note: This software is released under dual MIT and GPL licenses. A
+*    recipient may use this file under the terms of either the MIT license or
+*    GPL License. If you wish to use only one license not the other, you can
+*    indicate your decision by deleting one of the above license notices in your
+*    version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_metadata_h_
+#define __gc_hal_kernel_metadata_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Macro to combine four characters into a Character Code. */
+#define __FOURCC(a, b, c, d) \
+    ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define VIV_VIDMEM_METADATA_MAGIC __FOURCC('v', 'i', 'v', 'm')
+
+/* Compressed format now was defined same as dec400d, should be general. */
+typedef enum _VIV_COMPRESS_FMT
+{
+    _VIV_CFMT_ARGB8 = 0,
+    _VIV_CFMT_XRGB8,
+    _VIV_CFMT_AYUV,
+    _VIV_CFMT_UYVY,
+    _VIV_CFMT_YUY2,
+    _VIV_CFMT_YUV_ONLY,
+    _VIV_CFMT_UV_MIX,
+    _VIV_CFMT_ARGB4,
+    _VIV_CFMT_XRGB4,
+    _VIV_CFMT_A1R5G5B5,
+    _VIV_CFMT_X1R5G5B5,
+    _VIV_CFMT_R5G6B5,
+    _VIV_CFMT_Z24S8,
+    _VIV_CFMT_Z24,
+    _VIV_CFMT_Z16,
+    _VIV_CFMT_A2R10G10B10,
+    _VIV_CFMT_BAYER,
+    _VIV_CFMT_SIGNED_BAYER,
+    _VIV_CFMT_VAA16,
+    _VIV_CFMT_S8,
+
+    _VIV_CFMT_MAX,
+} _VIV_COMPRESS_FMT;
+
+/* Metadata for cross-device fd share with additional (ts) info. */
+typedef struct _VIV_VIDMEM_METADATA
+{
+    uint32_t magic;
+
+    int32_t  ts_fd;
+    void *   ts_dma_buf;
+#ifdef gcdANDROID
+    dma_addr_t ts_address;
+#endif
+
+    uint32_t fc_enabled;
+    uint32_t fc_value;
+    uint32_t fc_value_upper;
+
+    uint32_t compressed;
+    uint32_t compress_format;
+} _VIV_VIDMEM_METADATA;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_metadata_h_ */
+
+
index ead1fb2a2f9b61a91c0e81fd2cb219980106545e..9169bf2e736ea64f45e13c4d7a287655039a46d2 100644 (file)
@@ -414,52 +414,6 @@ This define enables the use of VM for gckCommand and fence buffers.
 #ifndef gcdGC355_VGMMU_MEMORY_SIZE_KB
 #   define gcdGC355_VGMMU_MEMORY_SIZE_KB   32
 #endif
-/*
-    gcdSECURE_USER
-
-        Use logical addresses instead of physical addresses in user land.  In
-        this case a hint table is created for both command buffers and context
-        buffers, and that hint table will be used to patch up those buffers in
-        the kernel when they are ready to submit.
-*/
-#ifndef gcdSECURE_USER
-#   define gcdSECURE_USER                       0
-#endif
-
-/*
-    gcdSECURE_CACHE_SLOTS
-
-        Number of slots in the logical to DMA address cache table.  Each time a
-        logical address needs to be translated into a DMA address for the GPU,
-        this cache will be walked.  The replacement scheme is LRU.
-*/
-#ifndef gcdSECURE_CACHE_SLOTS
-#   define gcdSECURE_CACHE_SLOTS                1024
-#endif
-
-/*
-    gcdSECURE_CACHE_METHOD
-
-        Replacement scheme used for Secure Cache.  The following options are
-        available:
-
-            gcdSECURE_CACHE_LRU
-                A standard LRU cache.
-
-            gcdSECURE_CACHE_LINEAR
-                A linear walker with the idea that an application will always
-                render the scene in a similar way, so the next entry in the
-                cache should be a hit most of the time.
-
-            gcdSECURE_CACHE_HASH
-                A 256-entry hash table.
-
-            gcdSECURE_CACHE_TABLE
-                A simple cache but with potential of a lot of cache replacement.
-*/
-#ifndef gcdSECURE_CACHE_METHOD
-#   define gcdSECURE_CACHE_METHOD               gcdSECURE_CACHE_HASH
-#endif
 
 /*
     gcdREGISTER_READ_FROM_USER
@@ -469,7 +423,7 @@ This define enables the use of VM for gckCommand and fence buffers.
         should only be in debug or development drops.
 */
 #ifndef gcdREGISTER_READ_FROM_USER
-#   define gcdREGISTER_READ_FROM_USER           0
+#   define gcdREGISTER_READ_FROM_USER           1
 #endif
 
 #ifndef gcdREGISTER_WRITE_FROM_USER
@@ -517,7 +471,7 @@ This define enables the use of VM for gckCommand and fence buffers.
 #if gcdFPGA_BUILD
 #   define gcdGPU_TIMEOUT                   2000000
 #else
-#   define gcdGPU_TIMEOUT                   20000
+#   define gcdGPU_TIMEOUT                   40000
 #endif
 #endif
 
@@ -768,6 +722,19 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdRATIO_FOR_SMALL_MEMORY            32
 #endif
 
+/*
+    gcdENABLE_GPU_1M_PAGE
+        When non-zero, GPU page size will be 1M until the pool is out of memory
+        and low-level to 4K pages. When zero, it uses 4k GPU pages.
+*/
+#ifndef gcdENABLE_GPU_1M_PAGE
+#if !gcdSECURITY && defined(LINUX)
+#   define gcdENABLE_GPU_1M_PAGE                1
+#else
+#   define gcdENABLE_GPU_1M_PAGE                0
+#endif
+#endif
+
 /*
     gcdCONTIGUOUS_SIZE_LIMIT
         When non-zero, size of video node from gcvPOOL_VIRTUAL contiguous is
@@ -1026,7 +993,7 @@ This define enables the use of VM for gckCommand and fence buffers.
  */
 
 #ifndef gcdINTERRUPT_STATISTIC
-#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDER_CE)
+#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDER_CE) || defined(__VXWORKS__)
 #   define gcdINTERRUPT_STATISTIC               1
 #else
 #   define gcdINTERRUPT_STATISTIC               0
@@ -1368,6 +1335,9 @@ VIV:gcdUSE_MMU_EXCEPTION
 
 #endif
 
+#define gcdHAL_TEST 1
+#define gcdUSE_ZWP_SYNCHRONIZATION 1
+
 /*
     gcdUSE_SINGLE_CONTEXT
         When enabled, will enable single context.
@@ -1376,6 +1346,15 @@ VIV:gcdUSE_MMU_EXCEPTION
 #   define gcdUSE_SINGLE_CONTEXT                   0
 #endif
 
+/*
+    gcdKERNEL_QUERY_PERFORMANCE_COUNTER_V8
+        When enabled, will enable query new performance counter of V8.0 in kernel
+        space.
+ */
+#ifndef gcdKERNEL_QUERY_PERFORMANCE_COUNTER_V8
+#   define gcdKERNEL_QUERY_PERFORMANCE_COUNTER_V8  0
+#endif
+
 #endif /* __gc_hal_options_h_ */
 
 
index bd4e5cb0f3e828e535a9566187b6401eec80197b..49e2cc46deb1f7c4470402d6a8e03b7130876e80 100644 (file)
@@ -594,7 +594,9 @@ extern "C" {
 #define VPNC_HIIDLECYCLES                (VPNG_HI + 16)
 #define VPNC_HIREAD8BYTE                 (VPNG_HI + 17)
 #define VPNC_HIWRITE8BYTE                (VPNG_HI + 18)
-#define VPNC_HI_COUNT                    VPNC_HIWRITE8BYTE - VPNG_HI
+#define VPNC_HIOCBREAD16BYTE             (VPNG_HI + 19)
+#define VPNC_HIOCBWRITE16BYTE            (VPNG_HI + 20)
+#define VPNC_HI_COUNT                    VPNC_HIOCBWRITE16BYTE - VPNG_HI
 
 /* HW: L2 Counters. */
 #define VPNC_L2AXI0READREQCOUNT          (VPNG_L2 + 1)
@@ -681,6 +683,12 @@ extern "C" {
 #define DEFAULT_PROFILE_FILE_NAME   "vprofiler.vpd"
 #endif
 
+#define VPHEADER_VERSION "VP20"
+
+#define VPFILETYPE_GL "10"
+
+#define VPFILETYPE_CL "00"
+
 #if gcdENDIAN_BIG
 #define BIG_ENDIAN_TRANS_INT(x) ((gctUINT32)(\
         (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
@@ -764,19 +772,19 @@ extern "C" {
 #define gcmGET_COUNTER(counter, counterId) \
     do \
     { \
-        if ((gctUINT32)*(memory + (counterId + offset) * clusterMaxID) == 0xdeaddead) \
+        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) \
         { \
             counter = 0xdeaddead; \
         } \
         else \
         { \
             gctUINT32 i; \
-            gctUINT64_PTR Memory = memory; \
+            gctUINT32_PTR Memory = memory; \
             counter = 0; \
-            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * clusterMaxID; \
-            for (i = 0; i < (gctUINT32)clusterMaxID; i++) \
+            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * (1 << clusterIDWidth); \
+            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) \
             { \
-                counter += (gctUINT32)*(Memory + (counterId + offset) * clusterMaxID + i); \
+                counter += *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i); \
             } \
         } \
     } \
@@ -785,19 +793,19 @@ extern "C" {
 #define gcmGET_LATENCY_COUNTER(minLatency, maxLatency, counterId) \
     do \
     { \
-        if ((gctUINT32)*(memory + (counterId + offset) * clusterMaxID) == 0xdeaddead) \
+        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) \
         { \
             minLatency = maxLatency = 0xdeaddead; \
         } \
         else \
         { \
             gctUINT32 i; \
-            gctUINT64_PTR Memory = memory; \
-            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * clusterMaxID; \
-            for (i = 0; i < (gctUINT32)clusterMaxID; i++) \
+            gctUINT32_PTR Memory = memory; \
+            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * (1 << clusterIDWidth); \
+            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) \
             { \
-                maxLatency += (((gctUINT32)*(Memory + (counterId + offset) * clusterMaxID + i) & 0xfff000) >> 12); \
-                minLatency += ((gctUINT32)*(Memory + (counterId + offset) * clusterMaxID + i) & 0x000fff); \
+                maxLatency += ((*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0xfff000) >> 12); \
+                minLatency += (*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0x000fff); \
                 if (minLatency == 4095) \
                     minLatency = 0; \
             } \
index 4b8f1fdc86b00ad59f4ed0d293e72a2fab14bb6b..1aba11c2e201010101c0b81111acddb807b33f0a 100644 (file)
@@ -339,6 +339,24 @@ gco2D_SetColorSourceEx(
     IN gctUINT32 TransparencyColor
     );
 
+/* Same as gco2D_SetColorSourceEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetColorSource64(
+    IN gco2D Engine,
+    IN gctUINT32 Address,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Stride,
+    IN gceSURF_FORMAT Format,
+    IN gceSURF_ROTATION Rotation,
+    IN gctUINT32 SurfaceWidth,
+    IN gctUINT32 SurfaceHeight,
+    IN gctBOOL CoordRelative,
+    IN gceSURF_TRANSPARENCY Transparency,
+    IN gctUINT32 TransparencyColor
+    );
+
 /* Configure color source. */
 gceSTATUS
 gco2D_SetColorSourceAdvanced(
@@ -389,6 +407,23 @@ gco2D_SetMaskedSourceEx(
     IN gctUINT32 SurfaceHeight
     );
 
+/* Same as gco2D_SetMaskedSourceEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetMaskedSource64(
+    IN gco2D Engine,
+    IN gctUINT32 Address,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Stride,
+    IN gceSURF_FORMAT Format,
+    IN gctBOOL CoordRelative,
+    IN gceSURF_MONOPACK MaskPack,
+    IN gceSURF_ROTATION Rotation,
+    IN gctUINT32 SurfaceWidth,
+    IN gctUINT32 SurfaceHeight
+    );
+
 /* Setup the source rectangle. */
 gceSTATUS
 gco2D_SetSource(
@@ -424,6 +459,20 @@ gco2D_SetTargetEx(
     IN gctUINT32 SurfaceHeight
     );
 
+/* Same as gco2D_SetTargetEx, but with better 64bit SW-path support.
+** Please do NOT export the API now.
+*/
+gceSTATUS
+gco2D_SetTarget64(
+    IN gco2D Engine,
+    IN gctUINT32 Address,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Stride,
+    IN gceSURF_ROTATION Rotation,
+    IN gctUINT32 SurfaceWidth,
+    IN gctUINT32 SurfaceHeight
+    );
+
 /* Calculate and program the stretch factors. */
 gceSTATUS
 gco2D_CalcStretchFactor(
index a9064debebc3a5f51de8345cbad80f06a5aa7f8d..7ded9c86f691260c2e82ac46925e67cdca87cc5b 100644 (file)
 #   include "linux/types.h"
 #elif defined(UNDER_CE)
 #include <crtdefs.h>
+typedef signed char        int8_t;
+typedef short              int16_t;
+typedef int                int32_t;
+typedef long long          int64_t;
+typedef unsigned char      uint8_t;
+typedef unsigned short     uint16_t;
+typedef unsigned int       uint32_t;
+typedef unsigned long long uint64_t;
 #elif defined(_MSC_VER) && (_MSC_VER <= 1500)
 #include <crtdefs.h>
 #include "vadefs.h"
@@ -136,6 +144,7 @@ extern "C" {
 #   error "gcmINLINE: Platform could not be determined"
 #endif
 
+
 /* Possible debug flags. */
 #define gcdDEBUG_NONE           0
 #define gcdDEBUG_ALL            (1 << 0)
@@ -263,6 +272,8 @@ typedef void *                  gctPOINTER;
 typedef const void *            gctCONST_POINTER;
 
 typedef char                    gctCHAR;
+typedef signed char             gctSIGNED_CHAR;
+typedef unsigned char           gctUNSIGNED_CHAR;
 typedef char *                  gctSTRING;
 typedef const char *            gctCONST_STRING;
 
@@ -485,7 +496,6 @@ typedef enum _gceSTATUS
     gcvSTATUS_DEVICE                =   -27,
     gcvSTATUS_NOT_MULTI_PIPE_ALIGNED =   -28,
     gcvSTATUS_OUT_OF_SAMPLER         =   -29,
-    gcvSTATUS_RESLUT_OVERFLOW       =   -30,
 
     /* Linker errors. */
     gcvSTATUS_GLOBAL_TYPE_MISMATCH              =   -1000,
@@ -861,7 +871,8 @@ gceSTATUS;
 **
 **      Return a value with all bytes in the 32 bit argument swapped.
 */
-#if defined(__GNUC__) && !defined(__KERNEL__)
+#if !defined(__KERNEL__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ >= 40300) \
+   && !defined(__VXWORKS__)
 #  define gcmBSWAP32(x)     __builtin_bswap32(x)
 #else
 #  define gcmBSWAP32(x) ((gctUINT32)(\
@@ -998,8 +1009,9 @@ typedef enum _gceTRACEMODE
     gcvTRACEMODE_NONE     = 0,
     gcvTRACEMODE_FULL     = 1,
     gcvTRACEMODE_LOGGER   = 2,
-    gcvTRACEMODE_PRE      = 3,
-    gcvTRACEMODE_POST     = 4,
+    gcvTRACEMODE_ALLZONE  = 3,
+    gcvTRACEMODE_PRE      = 4,
+    gcvTRACEMODE_POST     = 5,
 } gceTRACEMODE;
 
 typedef struct _gcsLISTHEAD * gcsLISTHEAD_PTR;
index 400c849b1b776e87245f030c5375a87ab90fc3de..94fb69116b01f64c8f1e1b81bd5c4b8bff4e8353 100644 (file)
 
 #define gcvVERSION_MAJOR        6
 
-#define gcvVERSION_MINOR        3
+#define gcvVERSION_MINOR        4
 
-#define gcvVERSION_PATCH        3
+#define gcvVERSION_PATCH        0
 
-#define gcvVERSION_BUILD     210826
+#define gcvVERSION_BUILD     229426
 
-#define gcvVERSION_STRING    "6.3.3.4.210826"
+#define gcvVERSION_STRING    "6.4.0.3.229426"
 
 #endif /* __gc_hal_version_h_ */
 
index d2f870506fac8dafdd8027b64a36cf09df44f91f..38753a26b60555d2b6aa95b9ba49d3afc1036e8a 100644 (file)
@@ -61,7 +61,6 @@ extern "C" {
 #endif
 
 
-#include "gc_hal_rename.h"
 #include "gc_hal_types.h"
 #include "gc_hal_enum.h"
 #include "gc_hal_base.h"
index f18932c3dc7a300e8d4eae13d3f55ce6511e5109..70c7c9d241904a559bc05ccde9ed82c17151d229 100755 (executable)
@@ -99,12 +99,9 @@ EXPORTS
     gcoOS_Send
     gcoOS_WaitForSend
     gcoOS_SetDebugFile
-    gcoOS_ReplaceDebugFile
     gcoOS_SetDebugLevel
-    gcoOS_SetDebugLevelZone
     gcoOS_SetDebugShaderFiles
     gcoOS_SetDebugZone
-    gcoOS_SetDebugZones
     gcoOS_SetDriverTLS
     gcoOS_SetPLSValue
     gcoOS_SetPos
@@ -250,6 +247,7 @@ EXPORTS
     gcoHAL_QueryCluster
     gcoHAL_QueryChipFeature
     gcoHAL_QueryChipIdentity
+    gcoHAL_QueryChipIdentityEx
     gcoHAL_QueryChipLimits
     gcoHAL_QueryPowerManagementState
     gcoHAL_QueryTiled
@@ -343,6 +341,7 @@ EXPORTS
     gcoSURF_WrapSurface
     gcoSURF_GetInfo
     gcoSURF_QueryHints
+    gcoSURF_UpdateMetadata
 
 !IF "$(VIVANTE_ENABLE_3D)_$(VIVANTE_ENABLE_VG)" != "0_0"
 ;   Both 3D & VG have these functions.
@@ -377,14 +376,14 @@ EXPORTS
     gcoSURF_GetFence
     gcoSURF_WaitFence
     gcoSURF_AlignResolveRect
-       gcoSURF_DrawBlit
+    gcoSURF_DrawBlit
     gcsSURF_NODE_Construct
     gcsSURF_NODE_Destroy
-       gcsSURF_NODE_Lock
-       gcsSURF_NODE_Unlock
+    gcsSURF_NODE_Lock
+    gcsSURF_NODE_Unlock
     gcsSURF_NODE_GetHardwareAddress
     gcsSURF_NODE_SetHardwareAddress
-       gcsSURF_NODE_GetHWAddress
+    gcsSURF_NODE_GetHWAddress
 
     gcoSURF_FlushTileStatus
     gcoSURF_AppendTileStatus
@@ -765,10 +764,10 @@ EXPORTS
        gcoVX_QueryHWChipInfo
     gcoVX_FlushCache
     gcoVX_AllocateMemoryEx
+    gcoVX_AllocateMemoryExAddAllocflag
     gcoVX_FreeMemoryEx
     gcoVX_GetMemorySize
     gcoVX_ZeroMemorySize
-    gcoVX_GetHWConfigGpuCount
     gcoVX_SwitchContext
     gcoVX_RestoreContext
     gcoVX_WaitNNEvent
@@ -780,8 +779,9 @@ EXPORTS
     gcoVX_VerifyHardware
     gcoVX_GetEvisNoInstFeatureCap
     gcoVX_QueryDeviceCount
-       gcoVX_CaptureInitState
-
+    gcoVX_QueryCoreCount
+    gcoVX_QueryMultiCore
+    gcoVX_CaptureInitState
 
 !IF "$(VSIMULATOR_DEBUG)" == "1"
     gcoOS_UpdateSimulatorCallback
index 19e743dba4e553879e654f845d06fef1b625294e..9a5bd4c7dc826630af40ac76e1e47a62bdd49294 100644 (file)
@@ -61,6 +61,9 @@
 #include <linux/mman.h>
 #include <asm/atomic.h>
 #include <linux/dma-mapping.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)
+#include <linux/dma-direct.h>
+#endif
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 
@@ -147,6 +150,7 @@ _DmaAlloc(
     gcmkHEADER_ARG("Mdl=%p NumPages=0x%zx Flags=0x%x", Mdl, NumPages, Flags);
 
     gcmkONERROR(gckOS_Allocate(os, sizeof(struct mdl_dma_priv), (gctPOINTER *)&mdlPriv));
+    mdlPriv->kvaddr = gcvNULL;
 
 #if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
     if (Flags & gcvALLOC_FLAG_4GB_ADDR)
@@ -166,7 +170,7 @@ _DmaAlloc(
     if ((os->device->baseAddress & 0x80000000) != (mdlPriv->dmaHandle & 0x80000000))
     {
         mdlPriv->dmaHandle = (mdlPriv->dmaHandle & ~0x80000000)
-                            | (os->device->baseAddress & 0x80000000);
+                           | (os->device->baseAddress & 0x80000000);
     }
 #endif
 
@@ -230,7 +234,14 @@ _DmaGetSGT(
         gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
     }
 
+#if !defined(phys_to_page)
     page = virt_to_page(mdlPriv->kvaddr);
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
+    page = phys_to_page(mdlPriv->dmaHandle);
+#else
+    page = phys_to_page(dma_to_phys(&Allocator->os->device->platform->device->dev, mdlPriv->dmaHandle));
+#endif
+
     for (i = 0; i < numPages; ++i)
     {
         pages[i] = nth_page(page, i + skipPages);
@@ -420,8 +431,6 @@ _DmaMapUser(
         struct vm_area_struct *vma = find_vma(current->mm, (unsigned long)userLogical);
         if (vma == gcvNULL)
         {
-            up_write(&current->mm->mmap_sem);
-
             gcmkTRACE_ZONE(
                 gcvLEVEL_INFO, gcvZONE_OS,
                 "%s(%d): find_vma error",
@@ -575,7 +584,8 @@ _DmaAlloctorInit(
      * DMA allocator is only used for NonPaged memory
      * when NO_DMA_COHERENT is not defined.
      */
-    allocator->capability = gcvALLOC_FLAG_DMABUF_EXPORTABLE
+    allocator->capability = gcvALLOC_FLAG_CONTIGUOUS
+                          | gcvALLOC_FLAG_DMABUF_EXPORTABLE
 #if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
                           | gcvALLOC_FLAG_4GB_ADDR
 #endif
index eb75e8b312606f6f85089e8456c5cbb13ea71ba8..97ab69804f70da3f30a8480f857b210992f6e8a6 100644 (file)
@@ -244,10 +244,10 @@ _DmabufAttach(
         npages += (sg_dma_len(s) + PAGE_SIZE - 1) / PAGE_SIZE;
     }
 
-    /* Allocate page arrary. */
+    /* Allocate page array. */
     gcmkONERROR(gckOS_Allocate(os, npages * gcmSIZEOF(*pagearray), (gctPOINTER *)&pagearray));
 
-    /* Fill page arrary. */
+    /* Fill page array. */
     for_each_sg(sgt->sgl, s, sgt->orig_nents, i)
     {
         for (j = 0; j < (sg_dma_len(s) + PAGE_SIZE - 1) / PAGE_SIZE; j++)
@@ -277,8 +277,7 @@ _DmabufAttach(
 
     Mdl->priv = buf_desc;
 
-    /* Always treat it as a non-contigous buffer. */
-    Mdl->contiguous = gcvFALSE;
+    Mdl->contiguous = (sgt->nents == 1) ? gcvTRUE : gcvFALSE;
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
index fc8d16a9c63409b463d32f8f6f66fc0d88a8ba53..421f43ccab9133059ce6b581e6d0f9cd1376e506 100644 (file)
@@ -101,6 +101,10 @@ struct gfp_mdl_priv
         {
             /* Pointer to a array of pointers to page. */
             struct page **nonContiguousPages;
+
+            struct page **Pages1M;
+            int numPages1M;
+            int *isExact;
             struct sg_table sgt;
         };
     };
@@ -273,6 +277,178 @@ _NonContiguousAlloc(
     return pages;
 }
 
+static void
+_NonContiguous1MPagesFree(
+    IN struct gfp_mdl_priv *MdlPriv,
+    IN gctUINT32 NumPages1M
+    )
+{
+    gctINT i;
+
+    if (MdlPriv->Pages1M && MdlPriv->isExact)
+    {
+        for (i = 0; i < NumPages1M && MdlPriv->Pages1M[i]; i++)
+        {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+            if (MdlPriv->isExact[i] == gcvTRUE)
+            {
+                free_pages_exact(page_address(MdlPriv->Pages1M[i]), gcd1M_PAGE_SIZE);
+            }
+            else
+#endif
+            {
+                __free_pages(MdlPriv->Pages1M[i], get_order(gcd1M_PAGE_SIZE));
+            }
+        }
+    }
+
+    if (MdlPriv->Pages1M)
+    {
+        if (is_vmalloc_addr(MdlPriv->Pages1M))
+        {
+            vfree(MdlPriv->Pages1M);
+        }
+        else
+        {
+            kfree(MdlPriv->Pages1M);
+        }
+    }
+
+    if (MdlPriv->isExact)
+    {
+         if (is_vmalloc_addr(MdlPriv->isExact))
+        {
+            vfree(MdlPriv->isExact);
+        }
+        else
+        {
+            kfree(MdlPriv->isExact);
+        }
+    }
+
+    if (MdlPriv->nonContiguousPages)
+    {
+        if (is_vmalloc_addr(MdlPriv->nonContiguousPages))
+        {
+            vfree(MdlPriv->nonContiguousPages);
+        }
+        else
+        {
+            kfree(MdlPriv->nonContiguousPages);
+        }
+    }
+}
+
+static struct page **
+_NonContiguous1MPagesAlloc(
+    IN struct gfp_mdl_priv *MdlPriv,
+    IN gctSIZE_T *NumPages,
+    IN gctUINT32 Gfp
+    )
+{
+    size_t numPages1M, num, size;
+    struct page **pages;
+    struct page *page;
+    void *addr = NULL;
+    gctINT i, j;
+
+    numPages1M = ((*NumPages << PAGE_SHIFT) + (gcd1M_PAGE_SIZE - 1)) >> gcd1M_PAGE_SHIFT;
+
+    *NumPages = (numPages1M << gcd1M_PAGE_SHIFT) >> PAGE_SHIFT;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
+        if (*NumPages > totalram_pages())
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+        if (*NumPages > totalram_pages)
+#else
+        if (*NumPages > num_physpages)
+#endif
+    {
+        return gcvNULL;
+    }
+
+    num = gcd1M_PAGE_SIZE / PAGE_SIZE;
+
+    size = numPages1M * sizeof(struct page *);
+    MdlPriv->Pages1M = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+    if (!MdlPriv->Pages1M)
+    {
+        MdlPriv->Pages1M = vmalloc(size);
+
+        if (!MdlPriv->Pages1M)
+        {
+            return gcvNULL;
+        }
+    }
+
+    size = numPages1M * sizeof(int);
+    MdlPriv->isExact = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+    if (!MdlPriv->isExact)
+    {
+        MdlPriv->isExact = vmalloc(size);
+        if (!MdlPriv->isExact)
+        {
+            _NonContiguous1MPagesFree(MdlPriv, 0);
+            return gcvNULL;
+        }
+    }
+
+    size = *NumPages * sizeof(struct page *);
+    pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+    if (!pages)
+    {
+        pages = vmalloc(size);
+        if (!pages)
+        {
+            _NonContiguous1MPagesFree(MdlPriv, 0);
+            return gcvNULL;
+        }
+    }
+
+    MdlPriv->numPages1M = 0;
+    for (i = 0; i < numPages1M; i++)
+    {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+        addr = alloc_pages_exact(gcd1M_PAGE_SIZE, (Gfp & ~__GFP_HIGHMEM) | __GFP_NORETRY);
+
+        MdlPriv->Pages1M[i] = addr ? virt_to_page(addr) : gcvNULL;
+        if (MdlPriv->Pages1M[i])
+        {
+            MdlPriv->isExact[i] = gcvTRUE;
+        }
+#endif
+
+        if (MdlPriv->Pages1M[i] == gcvNULL)
+        {
+            int order = get_order(gcd1M_PAGE_SIZE);
+
+            if (order >= MAX_ORDER)
+            {
+                _NonContiguous1MPagesFree(MdlPriv, MdlPriv->numPages1M);
+                return gcvNULL;
+            }
+
+            MdlPriv->Pages1M[i] = alloc_pages(Gfp, order);
+        }
+
+        if (MdlPriv->Pages1M[i] == gcvNULL)
+        {
+            _NonContiguous1MPagesFree(MdlPriv, MdlPriv->numPages1M);
+            return gcvNULL;
+        }
+
+        MdlPriv->numPages1M += 1;
+
+        for (j = 0; j < num; j++)
+        {
+            page = nth_page(MdlPriv->Pages1M[i], j);
+            pages[i * num + j] = page;
+        }
+    }
+
+    return pages;
+}
+
 /***************************************************************************\
 ************************ GFP Allocator **********************************
 \***************************************************************************/
@@ -318,14 +494,31 @@ _GFPAlloc(
     }
 
 #if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
-    if (Flags & gcvALLOC_FLAG_4GB_ADDR)
+    if ((Flags & gcvALLOC_FLAG_4GB_ADDR) || (Allocator->os->device->platform->flagBits & gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS))
     {
         /* remove __GFP_HIGHMEM bit, add __GFP_DMA32 bit */
         gfp &= ~__GFP_HIGHMEM;
         gfp |= __GFP_DMA32;
     }
+#else
+    if (Flags & gcvALLOC_FLAG_4GB_ADDR || (Allocator->os->device->platform->flagBits & gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS))
+    {
+        /* remove __GFP_HIGHMEM bit, add __GFP_DMA bit */
+        gfp &= ~__GFP_HIGHMEM;
+        gfp |= __GFP_DMA;
+    }
+
 #endif
 
+    if ((Flags & gcvALLOC_FLAG_NON_CONTIGUOUS) && (Flags & gcvALLOC_FLAG_1M_PAGES))
+    {
+        Mdl->pageUnit1M = gcvTRUE;
+    }
+    else
+    {
+        Mdl->pageUnit1M = gcvFALSE;
+    }
+
     if (contiguous)
     {
         size_t bytes = NumPages << PAGE_SHIFT;
@@ -354,7 +547,6 @@ _GFPAlloc(
             }
 
             mdlPriv->contiguousPages = alloc_pages(gfp, order);
-
         }
 
         if (mdlPriv->contiguousPages == gcvNULL)
@@ -394,7 +586,14 @@ _GFPAlloc(
     }
     else
     {
-        mdlPriv->nonContiguousPages = _NonContiguousAlloc(NumPages, gfp);
+        if (Mdl->pageUnit1M)
+        {
+            mdlPriv->nonContiguousPages = _NonContiguous1MPagesAlloc(mdlPriv, &NumPages, gfp);
+        }
+        else
+        {
+            mdlPriv->nonContiguousPages = _NonContiguousAlloc(NumPages, gfp);
+        }
 
         if (mdlPriv->nonContiguousPages == gcvNULL)
         {
@@ -416,7 +615,15 @@ _GFPAlloc(
 #endif
         if (result < 0)
         {
-            _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            if (Mdl->pageUnit1M)
+            {
+                _NonContiguous1MPagesFree(mdlPriv, mdlPriv->numPages1M);
+            }
+            else
+            {
+                _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            }
+
             gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
         }
 
@@ -425,7 +632,14 @@ _GFPAlloc(
 
         if (result != mdlPriv->sgt.nents)
         {
-            _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            if (Mdl->pageUnit1M)
+            {
+                _NonContiguous1MPagesFree(mdlPriv, mdlPriv->numPages1M);
+            }
+            else
+            {
+                _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            }
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
     && (defined (ARCH_HAS_SG_CHAIN) || defined (CONFIG_ARCH_HAS_SG_CHAIN))
@@ -462,7 +676,8 @@ _GFPAlloc(
 
         phys = page_to_phys(page);
 
-        BUG_ON(!phys);
+        /*for amlogic board, the page phys maybe start from 0x0000-0000*/
+        /*BUG_ON(!phys);*/
 
         if (PageHighMem(page))
         {
@@ -480,6 +695,7 @@ _GFPAlloc(
     atomic_add(high, &priv->high);
 
     Mdl->priv = mdlPriv;
+    Mdl->numPages = NumPages;
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -648,7 +864,14 @@ _GFPFree(
         set_pages_array_wb(mdlPriv->nonContiguousPages, Mdl->numPages);
 #endif
 
-        _NonContiguousFree(mdlPriv->nonContiguousPages, Mdl->numPages);
+        if (Mdl->pageUnit1M)
+        {
+            _NonContiguous1MPagesFree(mdlPriv, mdlPriv->numPages1M);
+        }
+        else
+        {
+            _NonContiguousFree(mdlPriv->nonContiguousPages, Mdl->numPages);
+        }
     }
 
     kfree(Mdl->priv);
@@ -975,6 +1198,9 @@ _GFPCache(
 {
     struct gfp_mdl_priv *mdlPriv = Mdl->priv;
     enum dma_data_direction dir;
+    dma_addr_t dma_addr = (mdlPriv->dma_addr + Offset) & PAGE_MASK;
+    gctSIZE_T bytes = (mdlPriv->dma_addr + Offset + Bytes) - dma_addr;
+    gctINT numPages = GetPageCount(bytes, 0);
 
     switch (Operation)
     {
@@ -984,7 +1210,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_device(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -999,7 +1225,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_device(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -1012,7 +1238,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_cpu(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -1027,7 +1253,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_cpu(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -1138,6 +1364,7 @@ _GFPAlloctorInit(
 #if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
                           | gcvALLOC_FLAG_4GB_ADDR
 #endif
+                          | gcvALLOC_FLAG_1M_PAGES
                           ;
 
 #if defined(gcdEMULATE_SECURE_ALLOCATOR)
index 45b3f0b8ed00a95b12068d103df775f4bb54f09c..5e390dba99a9818faa15650677d7ba3c0e8a2f26 100644 (file)
@@ -390,7 +390,6 @@ reserved_mem_map_kernel(
         return gcvSTATUS_INVALID_ARGUMENT;
     }
 
-    /* Should never run here now. */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
     vaddr = memremap(res->start + Offset, Bytes, MEMREMAP_WC);
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
index 76998191ee1f7ec14d9c106f11557071d8095863..c625509066da172f51496113ff7e721d3bc821e2 100644 (file)
@@ -59,6 +59,7 @@
 
 #include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/cache.h>
 
 #define _GC_OBJ_ZONE gcvZONE_ALLOCATOR
 
@@ -130,6 +131,12 @@ static int import_page_map(struct um_desc *um,
     int result;
     struct page **pages;
 
+    if ((addr & (cache_line_size() - 1)) || (size & (cache_line_size() - 1)))
+    {
+        /* Not cpu cacheline size aligned, can not support. */
+        return -EINVAL;
+    }
+
     pages = kzalloc(page_count * sizeof(void *), GFP_KERNEL | gcdNOWARN);
     if (!pages)
         return -ENOMEM;
@@ -216,9 +223,9 @@ error:
     kfree(um->sgt.sgl);
 #endif
 
-    if (um->pages)
+    if (pages)
     {
-        kfree(um->pages);
+        kfree(pages);
     }
     return result;
 }
@@ -463,6 +470,47 @@ _Import(
         gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
     }
 
+    if(Os->device->platform->flagBits & gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS )
+    {
+        gctPHYS_ADDR_T addr;
+
+        if (Physical != gcvINVALID_PHYSICAL_ADDRESS)
+        {
+            if(Physical > 0xFFFFFFFFu || Physical + Size > 0xFFFFFFFFu )
+            {
+                gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+            }
+        }
+        else if (vm_flags & VM_PFNMAP)
+        {
+            for(i = 0; i < pageCount; i++)
+            {
+                addr =  UserMemory->pfns[i] << PAGE_SHIFT;
+                if( addr > 0xFFFFFFFFu)
+                {
+                    kfree(UserMemory->pfns);
+                    UserMemory->pfns = gcvNULL;
+                    kfree(UserMemory->refs) ;
+                    UserMemory->refs = gcvNULL;
+                    gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+                }
+            }
+        }
+        else
+        {
+            for (i = 0; i< pageCount; i++)
+            {
+                addr = page_to_phys(UserMemory->pages[i]);
+                if(addr > 0xFFFFFFFFu )
+                {
+                    kfree(UserMemory->pages);
+                    UserMemory->pages = gcvNULL;
+                    gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+                }
+            }
+        }
+    }
+
     UserMemory->vm_flags = vm_flags;
     UserMemory->user_vaddr = (unsigned long)Memory;
     UserMemory->size  = Size;
index 63efc3d836646e36ce8421aafe8c9a2172a41460..d607ee222e3ce4025ebb31cd4c9a83105984c3ca 100644 (file)
 #include <linux/time.h>
 #include <stdarg.h>
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
+#include <linux/nmi.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index 0c77d9787f7adc368cbd8ac493e521b4d226a31d..bcc304c72d231d305cbbcb4252bbe8da94a86ec9 100644 (file)
@@ -89,6 +89,9 @@ int gc_info_show(struct seq_file* m, void* data)
     gctUINT32 productID = 0;
     gctUINT32 ecoID = 0;
 
+    if (!device)
+        return -ENXIO;
+
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
         if (device->kernels[i])
@@ -127,6 +130,9 @@ int gc_clients_show(struct seq_file* m, void* data)
     gctINT i, pid;
     char name[24];
 
+    if (!kernel)
+        return -ENXIO;
+
     seq_printf(m, "%-8s%s\n", "PID", "NAME");
     seq_printf(m, "------------------------\n");
 
@@ -171,6 +177,9 @@ int gc_meminfo_show(struct seq_file* m, void* data)
     gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
     gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0};
 
+    if (!kernel)
+        return -ENXIO;
+
     status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory);
 
     if (gcmIS_SUCCESS(status))
@@ -315,9 +324,9 @@ _ShowVideoMemoryRecord(
                 continue;
             }
 
-            gckVIDMEM_NODE_GetPhysical(record->kernel, nodeObject, 0, &physical);
-            gckVIDMEM_NODE_GetReference(record->kernel, nodeObject, &refCount);
-            gckVIDMEM_NODE_GetLockCount(record->kernel, nodeObject, &lockCount);
+            gcmkONERROR(gckVIDMEM_NODE_GetPhysical(record->kernel, nodeObject, 0, &physical));
+            gcmkONERROR(gckVIDMEM_NODE_GetReference(record->kernel, nodeObject, &refCount));
+            gcmkONERROR(gckVIDMEM_NODE_GetLockCount(record->kernel, nodeObject, &lockCount));
 
             seq_printf(m, "%#8x %#18lx %10lu %12s %8s %#12llx %4d %4d\n",
                 handle,
@@ -331,6 +340,9 @@ _ShowVideoMemoryRecord(
                 );
         }
     }
+
+OnError:
+    return;
 }
 
 static void
@@ -602,6 +614,9 @@ gc_db_show(struct seq_file *m, void *data)
     gckGALDEVICE device = node->device;
     gckKERNEL kernel = _GetValidKernel(device);
 
+    if (!kernel)
+        return -ENXIO;
+
     /* Acquire the database mutex. */
     gcmkVERIFY_OK(
         gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
@@ -638,7 +653,14 @@ gc_version_show(struct seq_file *m, void *data)
 {
     gcsINFO_NODE *node = m->private;
     gckGALDEVICE device = node->device;
-    gcsPLATFORM * platform = device->platform;
+    gcsPLATFORM * platform = gcvNULL;
+
+    if (!device)
+        return -ENXIO;
+
+    platform = device->platform;
+    if (!platform)
+        return -ENXIO;
 
     seq_printf(m, "%s built at %s\n",  gcvVERSION_STRING, HOST);
 
@@ -706,6 +728,9 @@ gc_idle_show(struct seq_file *m, void *data)
     gctUINT64 idle;
     gctUINT64 suspend;
 
+    if (!kernel)
+        return -ENXIO;
+
     gckHARDWARE_QueryStateTimer(kernel->hardware, &on, &off, &idle, &suspend);
 
     /* Idle time since last call */
@@ -755,6 +780,10 @@ gc_dump_trigger_show(struct seq_file *m, void *data)
     {
         kernel = device->kernels[dumpCore];
     }
+
+    if (!kernel)
+        return -ENXIO;
+
 #endif
 
     seq_printf(m, gcdDEBUG_FS_WARN);
@@ -850,6 +879,9 @@ static int gc_vidmem_show(struct seq_file *m, void *unused)
 
     gckKERNEL kernel = _GetValidKernel(device);
 
+    if (!kernel)
+        return -ENXIO;
+
     if (dumpProcess == 0)
     {
         /* Acquire the database mutex. */
@@ -929,8 +961,10 @@ static int gc_clk_show(struct seq_file* m, void* data)
     gcsINFO_NODE *node = m->private;
     gckGALDEVICE device = node->device;
     gctUINT i;
+    gceSTATUS status;
 
-    gckGALDEVICE_QueryFrequency(device);
+    if (!device)
+        return -ENXIO;
 
     for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
     {
@@ -943,6 +977,13 @@ static int gc_clk_show(struct seq_file* m, void* data)
                 continue;
             }
 
+            status = gckHARDWARE_QueryFrequency(hardware);
+            if (gcmIS_ERROR(status))
+            {
+                seq_printf(m, "query gpu%d clock fail.\n", i);
+                continue;
+            }
+
             if (hardware->mcClk)
             {
                 seq_printf(m, "gpu%d mc clock: %d HZ.\n", i, hardware->mcClk);
@@ -1187,7 +1228,10 @@ _SetupContiguousVidMem(
         }
     }
 
-    printk(KERN_INFO "Galcore ContiguousBase=0x%llx ContiguousSize=0x%x\n", device->contiguousBase, (gctUINT32)device->contiguousSize);
+    if (Args->showArgs)
+    {
+        gcmkPRINT("Galcore Info: ContiguousBase=0x%llx ContiguousSize=0x%zx\n", device->contiguousBase, device->contiguousSize);
+    }
 
 OnError:
     gcmkFOOTER();
@@ -1330,7 +1374,10 @@ static int threadRoutine(void *ctxt)
         int down;
 
         down = down_interruptible(&device->semas[core]);
-        if (down) {} /* To make gcc 4.6 happy. */
+        if (down && down != -EINTR)
+        {
+            return down;
+        }
 
         if (unlikely(device->killThread))
         {
@@ -1426,7 +1473,7 @@ gckGALDEVICE_Construct(
 {
     gckKERNEL kernel = gcvNULL;
     gckGALDEVICE device;
-    gctINT32 i;
+    gctINT32 i, j;
     gceHARDWARE_TYPE type;
     gceSTATUS status = gcvSTATUS_OK;
 
@@ -1443,6 +1490,8 @@ gckGALDEVICE_Construct(
     memset(device, 0, sizeof(struct _gckGALDEVICE));
 
     device->platform = Platform;
+    device->platform->dev = gcvNULL;
+
     device->args = *Args;
 
     /* Clear irq lines. */
@@ -1454,8 +1503,6 @@ gckGALDEVICE_Construct(
 #endif
     }
 
-    gcmkONERROR(_DebugfsInit(device));
-
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
         device->irqLines[i]                  = Args->irqs[i];
@@ -1526,12 +1573,22 @@ gckGALDEVICE_Construct(
     device->baseAddress = device->physBase = Args->baseAddress;
     device->physSize = Args->physSize;
 
+    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+    {
+        device->extSRAMBases[i] = Args->extSRAMBases[i];
+        device->extSRAMSizes[i] = Args->extSRAMSizes[i];
+    }
+
     /* Construct the gckOS object. */
     gcmkONERROR(gckOS_Construct(device, &device->os));
 
     /* Construct the gckDEVICE object for os independent core management. */
     gcmkONERROR(gckDEVICE_Construct(device->os, &device->device));
 
+    device->device->showSRAMMapInfo = Args->showArgs;
+
+    device->platform->dev = device->device;
+
     if (device->irqLines[gcvCORE_MAJOR] != -1)
     {
         gcmkONERROR(gctaOS_ConstructOS(device->os, &device->taos));
@@ -1566,7 +1623,7 @@ gckGALDEVICE_Construct(
             Args->compression
             ));
 
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
             device->kernels[gcvCORE_MAJOR]->hardware,
             Args->powerManagement
             ));
@@ -1616,7 +1673,7 @@ gckGALDEVICE_Construct(
             gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
         }
 
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
             device->kernels[gcvCORE_2D]->hardware,
             Args->powerManagement
             ));
@@ -1665,7 +1722,7 @@ gckGALDEVICE_Construct(
                 Args->compression
                 ));
 
-            gcmkONERROR(gckHARDWARE_SetPowerManagement(
+            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
                 device->kernels[i]->hardware,
                 Args->powerManagement
                 ));
@@ -1677,6 +1734,60 @@ gckGALDEVICE_Construct(
         }
     }
 
+    /* Setup external SRAM memory region. */
+    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+    {
+        if (!device->extSRAMSizes[i])
+        {
+            /* Keep this path for internal test, read from feature database. */
+            device->extSRAMSizes[i] = device->device->extSRAMSizes[i];
+        }
+
+        if (device->extSRAMSizes[i] > 0)
+        {
+            /* create the external SRAM memory heap */
+            status = gckVIDMEM_Construct(
+                device->os,
+                device->extSRAMBases[i],
+                device->extSRAMSizes[i],
+                64,
+                0,
+                &device->extSRAMVidMem[i]
+                );
+
+            if (gcmIS_ERROR(status))
+            {
+                /* Error, disable external SRAM heap. */
+                device->extSRAMSizes[i] = 0;
+            }
+            else
+            {
+                char sRAMName[20];
+                snprintf(sRAMName, gcmSIZEOF(sRAMName) - 1, "Galcore external sram%d", i);
+
+                /* Map external SRAM memory. */
+                gcmkONERROR(gckOS_RequestReservedMemory(
+                        device->os,
+                        device->extSRAMBases[i], device->extSRAMSizes[i],
+                        sRAMName,
+                        device->args.sRAMRequested,
+                        &device->extSRAMPhysical[i]
+                        ));
+
+                device->extSRAMVidMem[i]->physical = device->extSRAMPhysical[i];
+                device->device->extSRAMPhysical[i] = device->extSRAMPhysical[i];
+
+                for (j = 0; j < gcdMAX_GPU_COUNT; j++)
+                {
+                    if (device->irqLines[j] != -1 && device->kernels[j])
+                    {
+                        device->kernels[j]->hardware->options.extSRAMGPUPhysNames[i] = gckKERNEL_AllocateNameFromPointer(device->kernels[j], device->extSRAMPhysical[i]);
+                    }
+                }
+            }
+        }
+    }
+
     /* Initialize the kernel thread semaphores. */
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
@@ -1749,6 +1860,8 @@ gckGALDEVICE_Construct(
         device->contiguousPhysName = gcmPTR_TO_NAME(device->contiguousPhysical);
     }
 
+    gcmkONERROR(_DebugfsInit(device));
+
     /* Return pointer to the device. */
     *Device = galDevice = device;
 
@@ -1822,33 +1935,30 @@ gckGALDEVICE_Destroy(
         }
 
         /* Destroy per-core SRAM heap. */
-        if (Device->args.sRAMMode)
+        for (i = 0; i < gcvCORE_COUNT; i++)
         {
-            for (i = 0; i <= gcvCORE_3D_MAX; i++)
+            if (Device->kernels[i])
             {
                 kernel = Device->kernels[i];
 
-                if (kernel && kernel->sRAMNonExclusive)
+                for (j = gcvSRAM_INTERNAL0; j < gcvSRAM_INTER_COUNT; j++)
                 {
-                    for (j = gcvSRAM_EXTERNAL0; j < gcvSRAM_COUNT; j++)
+                    if (kernel->sRAMPhysical[j] != gcvNULL)
                     {
-                        if (kernel->sRAMPhysical[j] != gcvNULL)
-                        {
-                            /* Release reserved SRAM memory. */
-                            gckOS_ReleaseReservedMemory(
-                                Device->os,
-                                kernel->sRAMPhysical[j]
-                                );
-
-                            kernel->sRAMPhysical[j] = gcvNULL;
-                        }
-
-                        if (kernel->sRAMVideoMem[j] != gcvNULL)
-                        {
-                            /* Destroy the SRAM contiguous heap. */
-                            gcmkVERIFY_OK(gckVIDMEM_Destroy(kernel->sRAMVideoMem[j]));
-                            kernel->sRAMVideoMem[j] = gcvNULL;
-                        }
+                        /* Release reserved SRAM memory. */
+                        gckOS_ReleaseReservedMemory(
+                            Device->os,
+                            kernel->sRAMPhysical[j]
+                            );
+
+                        kernel->sRAMPhysical[j] = gcvNULL;
+                    }
+
+                    if (kernel->sRAMVidMem[j] != gcvNULL)
+                    {
+                        /* Destroy the SRAM contiguous heap. */
+                        gcmkVERIFY_OK(gckVIDMEM_Destroy(kernel->sRAMVidMem[j]));
+                        kernel->sRAMVidMem[j] = gcvNULL;
                     }
                 }
             }
@@ -1876,6 +1986,23 @@ gckGALDEVICE_Destroy(
             Device->internalVidMem = gcvNULL;
         }
 
+        for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+        {
+            if (Device->extSRAMPhysical[i] != gcvNULL)
+            {
+                gckOS_ReleaseReservedMemory(
+                    Device->os,
+                    Device->extSRAMPhysical[i]
+                    );
+            }
+
+            if (Device->extSRAMVidMem[i] != gcvNULL)
+            {
+                gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->extSRAMVidMem[i]));
+                Device->extSRAMVidMem[i] = gcvNULL;
+            }
+        }
+
         if (Device->externalPhysical != gcvNULL)
         {
             gckOS_ReleaseReservedMemory(
@@ -1990,99 +2117,6 @@ gckGALDEVICE_Destroy(
     return gcvSTATUS_OK;
 }
 
-/*******************************************************************************
-**
-**  gckGALDEVICE_QueryFrequency
-**
-**  Query frequency for all the hardwares.
-**
-*/
-gceSTATUS
-gckGALDEVICE_QueryFrequency(
-    IN gckGALDEVICE Device
-    )
-{
-    gctUINT64 mcStart[gcvCORE_COUNT], shStart[gcvCORE_COUNT];
-    gctUINT32 mcClk[gcvCORE_COUNT], shClk[gcvCORE_COUNT];
-    gckHARDWARE hardware = gcvNULL;
-    gceSTATUS status;
-    gctUINT i;
-
-    gcmkHEADER_ARG("Device=0x%p", Device);
-
-    for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
-    {
-        if (i == gcvCORE_VG)
-        {
-            continue;
-        }
-
-        if (Device->kernels[i])
-        {
-            hardware = Device->kernels[i]->hardware;
-
-            mcStart[i] = shStart[i] = 0;
-
-            if (Device->args.powerManagement)
-            {
-                gcmkONERROR(gckHARDWARE_SetPowerManagement(
-                    hardware, gcvFALSE
-                    ));
-            }
-
-            gcmkONERROR(gckHARDWARE_SetPowerManagementState(
-                hardware, gcvPOWER_ON_AUTO
-                ));
-
-            gckHARDWARE_EnterQueryClock(hardware,
-                                        &mcStart[i], &shStart[i]);
-        }
-    }
-
-    gcmkONERROR(gckOS_Delay(Device->os, 50));
-
-    for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
-    {
-        mcClk[i] = shClk[i] = 0;
-
-        if (i == gcvCORE_VG)
-        {
-            continue;
-        }
-
-        if (Device->kernels[i])
-        {
-            hardware = Device->kernels[i]->hardware;
-
-            if (mcStart[i])
-            {
-                gckHARDWARE_ExitQueryClock(hardware,
-                                           mcStart[i], shStart[i],
-                                           &mcClk[i], &shClk[i]);
-            }
-
-            hardware->mcClk = mcClk[i];
-            hardware->shClk = shClk[i];
-
-            if (Device->args.powerManagement)
-            {
-                gcmkONERROR(gckHARDWARE_SetPowerManagement(
-                    hardware, gcvTRUE
-                    ));
-            }
-        }
-    }
-
-    gcmkFOOTER_NO();
-
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-
-    return status;
-}
-
 /*******************************************************************************
 **
 **  gckGALDEVICE_Start
@@ -2141,7 +2175,7 @@ gckGALDEVICE_Start(
         else
         {
             /* Switch to SUSPEND power state. */
-            gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+            gcmkONERROR(gckHARDWARE_SetPowerState(
                 Device->kernels[i]->hardware, gcvPOWER_OFF_BROADCAST
                 ));
         }
@@ -2196,12 +2230,12 @@ gckGALDEVICE_Stop(
         }
         else
         {
-            gcmkONERROR(gckHARDWARE_SetPowerManagement(
+            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
                 Device->kernels[i]->hardware, gcvTRUE
                 ));
 
             /* Switch to OFF power state. */
-            gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+            gcmkONERROR(gckHARDWARE_SetPowerState(
                 Device->kernels[i]->hardware, gcvPOWER_OFF
                 ));
         }
index 298bfbee3e1763980153f128f8e1ba7873140e72..4d96458bbbe2358d52975d5ebc6b8cc5bb5dc542 100644 (file)
@@ -86,6 +86,12 @@ typedef struct _gckGALDEVICE
     gctPOINTER          externalLogical;
     gckVIDMEM           externalVidMem;
 
+    /* Shared external SRAMs. */
+    gctPHYS_ADDR_T      extSRAMBases[gcvSRAM_EXT_COUNT];
+    gctSIZE_T           extSRAMSizes[gcvSRAM_EXT_COUNT];
+    gctPHYS_ADDR        extSRAMPhysical[gcvSRAM_EXT_COUNT];
+    gckVIDMEM           extSRAMVidMem[gcvSRAM_EXT_COUNT];
+
     gctPHYS_ADDR_T      contiguousBase;
     gctSIZE_T           contiguousSize;
     gctPHYS_ADDR        contiguousPhysical;
@@ -150,14 +156,10 @@ typedef struct _gcsHAL_PRIVATE_DATA
      * closes it.
      */
     gctUINT32           pidOpen;
+    gctBOOL             isLocked;
 }
 gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR;
 
-gceSTATUS
-gckGALDEVICE_QueryFrequency(
-    IN gckGALDEVICE Device
-    );
-
 gceSTATUS
 gckGALDEVICE_Start(
     IN gckGALDEVICE Device
index 1645bad8fa7c5697ccc2ff7e671d3fce70f27144..300426a20f7e76a7e531f14b3dee8039355dd59a 100644 (file)
@@ -70,9 +70,9 @@ MODULE_DESCRIPTION("Vivante Graphics Driver");
 MODULE_LICENSE("Dual MIT/GPL");
 
 
-static struct class* gpuClass;
+static struct class* gpuClass = NULL;
 
-static gcsPLATFORM *platform;
+static gcsPLATFORM *platform = NULL;
 
 static gckGALDEVICE galDevice;
 
@@ -88,7 +88,7 @@ static ulong registerMemBase = 0x80000000;
 module_param(registerMemBase, ulong, 0644);
 MODULE_PARM_DESC(registerMemBase, "Base of bus address of GC core AHB register");
 
-static ulong registerMemSize = 2 << 10;
+static ulong registerMemSize = 2 << 16;
 module_param(registerMemSize, ulong, 0644);
 MODULE_PARM_DESC(registerMemSize, "Size of bus address range of GC core AHB register");
 
@@ -100,7 +100,7 @@ static ulong registerMemBase2D = 0x00000000;
 module_param(registerMemBase2D, ulong, 0644);
 MODULE_PARM_DESC(registerMemBase2D, "Base of bus address of G2D core if registerMemBase2D is used for a G3D core");
 
-static ulong registerMemSize2D = 2 << 10;
+static ulong registerMemSize2D = 2 << 16;
 module_param(registerMemSize2D, ulong, 0644);
 MODULE_PARM_DESC(registerMemSize2D, "Size of bus address range of G2D core if registerMemSize is used for a G3D core");
 
@@ -131,18 +131,29 @@ static ulong contiguousSize = gcdDEFAULT_CONTIGUOUS_SIZE;
 module_param(contiguousSize, ulong, 0644);
 MODULE_PARM_DESC(contiguousSize, "Size of memory reserved for GC");
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+static gctPHYS_ADDR_T contiguousBase = 0;
+module_param(contiguousBase, ullong, 0644);
+#else
 static ulong contiguousBase = 0;
 module_param(contiguousBase, ulong, 0644);
+#endif
 MODULE_PARM_DESC(contiguousBase, "Base address of memory reserved for GC, if it is 0, GC driver will try to allocate a buffer whose size defined by contiguousSize");
 
 static ulong externalSize = 0;
 module_param(externalSize, ulong, 0644);
 MODULE_PARM_DESC(externalSize, "Size of external memory, if it is 0, means there is no external pool");
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+static gctPHYS_ADDR_T externalBase = 0;
+module_param(externalBase, ullong, 0644);
+#else
 static ulong externalBase = 0;
 module_param(externalBase, ulong, 0644);
+#endif
 MODULE_PARM_DESC(externalBase, "Base address of external memory");
 
+
 static int fastClear = -1;
 module_param(fastClear, int, 0644);
 MODULE_PARM_DESC(fastClear, "Disable fast clear if set it to 0, enabled by default");
@@ -176,7 +187,7 @@ static uint stuckDump = 0;
 module_param(stuckDump, uint, 0644);
 MODULE_PARM_DESC(stuckDump, "Level of stuck dump content (1: Minimal, 2: Middle, 3: Maximal)");
 
-static int showArgs = 1;
+static int showArgs = 0;
 module_param(showArgs, int, 0644);
 MODULE_PARM_DESC(showArgs, "Display parameters value when driver loaded");
 
@@ -192,7 +203,7 @@ static uint registerBases[gcvCORE_COUNT];
 module_param_array(registerBases, uint, NULL, 0644);
 MODULE_PARM_DESC(registerBases, "Array of bases of bus address of register of multi-GPU");
 
-static uint registerSizes[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = 2 << 10};
+static uint registerSizes[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = 2 << 16};
 module_param_array(registerSizes, uint, NULL, 0644);
 MODULE_PARM_DESC(registerSizes, "Array of sizes of bus address range of register of multi-GPU");
 
@@ -212,19 +223,41 @@ static int smallBatch = 1;
 module_param(smallBatch, int, 0644);
 MODULE_PARM_DESC(smallBatch, "Enable/disable small batch");
 
-static gctPHYS_ADDR_T sRAMBases[gcvSRAM_COUNT * gcvCORE_COUNT] = {[0 ... gcvSRAM_COUNT * gcvCORE_COUNT - 1] = gcvINVALID_PHYSICAL_ADDRESS};
+/*******************************************************************************
+***************************** SRAM description *********************************
+*******************************************************************************/
+
+/* Per-core SRAM physical address base, the order of configuration is according to access speed, gcvINVALID_PHYSICAL_ADDRESS means no bus address. */
+static gctPHYS_ADDR_T sRAMBases[gcvSRAM_INTER_COUNT * gcvCORE_COUNT] = {[0 ... gcvSRAM_INTER_COUNT * gcvCORE_COUNT - 1] = gcvINVALID_PHYSICAL_ADDRESS};
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
 module_param_array(sRAMBases, ullong, NULL, 0644);
 MODULE_PARM_DESC(sRAMBases, "Array of base of bus address of SRAM,INTERNAL, EXTERNAL0, EXTERNAL1..., gcvINVALID_PHYSICAL_ADDRESS means no bus address");
 #endif
 
-static uint sRAMSizes[gcvSRAM_COUNT * gcvCORE_COUNT] = {[0 ... gcvSRAM_COUNT * gcvCORE_COUNT - 1] = 0};
+/* Per-core SRAM size. */
+static uint sRAMSizes[gcvSRAM_INTER_COUNT * gcvCORE_COUNT] = {[0 ... gcvSRAM_INTER_COUNT * gcvCORE_COUNT - 1] = 0};
 module_param_array(sRAMSizes, uint, NULL, 0644);
-MODULE_PARM_DESC(sRAMSizes, "Array of size of SRAM,INTERNAL, EXTERNAL0, EXTERNAL1..., 0 means no SRAM");
+MODULE_PARM_DESC(sRAMSizes, "Array of size of per-core SRAMs, 0 means no SRAM");
+
+/* Shared SRAM physical address bases. */
+static gctPHYS_ADDR_T extSRAMBases[gcvSRAM_EXT_COUNT] = {[0 ... gcvSRAM_EXT_COUNT - 1] = gcvINVALID_PHYSICAL_ADDRESS};
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+module_param_array(extSRAMBases, ullong, NULL, 0644);
+MODULE_PARM_DESC(extSRAMBases, "Shared SRAM physical address bases.");
+#endif
+
+/* Shared SRAM sizes. */
+static uint extSRAMSizes[gcvSRAM_EXT_COUNT] = {[0 ... gcvSRAM_EXT_COUNT - 1] = 0};
+module_param_array(extSRAMSizes, uint, NULL, 0644);
+MODULE_PARM_DESC(extSRAMSizes, "Shared SRAM sizes.");
 
-static uint sRAMMode = 0;
-module_param(sRAMMode, uint, 0644);
-MODULE_PARM_DESC(sRAMMode, "Default 0 means SRAM is exclusive mode usage, 1 means contiguous memory heap usage.");
+static uint sRAMRequested = 1;
+module_param(sRAMRequested, uint, 0644);
+MODULE_PARM_DESC(sRAMRequested, "Default 1 means AXI-SRAM is already reserved for GPU, 0 means GPU driver need request the memory region.");
+
+static uint sRAMLoopMode = 0;
+module_param(sRAMLoopMode, uint, 0644);
+MODULE_PARM_DESC(sRAMLoopMode, "Default 0 means SRAM pool must be specified when allocating SRAM memory, 1 means SRAM memory will be looped as default pool.");
 
 #if USE_LINUX_PCIE
 static int bar = 1;
@@ -234,8 +267,24 @@ MODULE_PARM_DESC(bar, "PCIE Bar index of GC core");
 static int bars[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = -1};
 module_param_array(bars, int, NULL, 0644);
 MODULE_PARM_DESC(bars, "Array of bar index of PCIE platform for multi-GPU");
+
+static uint regOffsets[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = 0};
+module_param_array(regOffsets, uint, NULL, 0644);
+MODULE_PARM_DESC(regOffsets, "Array of register offsets in corresponding BAR space");
+
+static int sRAMBars[gcvSRAM_EXT_COUNT] = {[0 ... gcvSRAM_EXT_COUNT - 1] = -1};
+module_param_array(sRAMBars, int, NULL, 0644);
+MODULE_PARM_DESC(sRAMBars, "Array of SRAM bar index of shared external SRAMs.");
+
+static int sRAMOffsets[gcvSRAM_EXT_COUNT] = {[0 ... gcvSRAM_EXT_COUNT - 1] = -1};
+module_param_array(sRAMOffsets, int, NULL, 0644);
+MODULE_PARM_DESC(sRAMOffsets, "Array of SRAM offset inside bar of shared external SRAMs.");
 #endif
 
+static uint mmuPageTablePool = 1;
+module_param(mmuPageTablePool, uint, 0644);
+MODULE_PARM_DESC(mmuPageTablePool, "Default 1 means alloc mmu page table in virsual memory, 0 means auto select memory pool.");
+
 
 static int gpu3DMinClock = 1;
 static int contiguousRequested = 0;
@@ -263,6 +312,7 @@ _InitModuleParam(
         }
 #if USE_LINUX_PCIE
         p->bars[i] = bars[i];
+        p->regOffsets[i] = regOffsets[i];
 #endif
     }
 
@@ -323,14 +373,25 @@ _InitModuleParam(
 
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
-        for (j = 0; j < gcvSRAM_COUNT; j++)
+        for (j = 0; j < gcvSRAM_INTER_COUNT; j++)
         {
-            p->sRAMBases[i][j] = sRAMBases[i * gcvSRAM_COUNT + j];
-            p->sRAMSizes[i][j] = sRAMSizes[i * gcvSRAM_COUNT + j];
+            p->sRAMBases[i][j] = sRAMBases[i * gcvSRAM_INTER_COUNT + j];
+            p->sRAMSizes[i][j] = sRAMSizes[i * gcvSRAM_INTER_COUNT + j];
         }
     }
 
-    p->sRAMMode = sRAMMode;
+    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+    {
+        p->extSRAMBases[i] = extSRAMBases[i];
+        p->extSRAMSizes[i] = extSRAMSizes[i];
+#if USE_LINUX_PCIE
+        p->sRAMBars[i]     = sRAMBars[i];
+        p->sRAMOffsets[i]  = sRAMOffsets[i];
+#endif
+    }
+
+    p->sRAMRequested = sRAMRequested;
+    p->sRAMLoopMode = sRAMLoopMode;
 
     p->baseAddress = baseAddress;
     p->physSize    = physSize;
@@ -384,6 +445,7 @@ _SyncModuleParam(
         registerSizes[i] = (ulong)p->registerSizes[i];
  #if USE_LINUX_PCIE
         bars[i]          = p->bars[i];
+        regOffsets[i]    = p->regOffsets[i];
  #endif
     }
 
@@ -418,14 +480,26 @@ _SyncModuleParam(
 
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
-        for (j = 0; j < gcvSRAM_COUNT; j++)
+        for (j = 0; j < gcvSRAM_INTER_COUNT; j++)
         {
-            sRAMBases[i * gcvSRAM_COUNT + j] = p->sRAMBases[i][j];
-            sRAMSizes[i * gcvSRAM_COUNT + j] = p->sRAMSizes[i][j];
+            sRAMBases[i * gcvSRAM_INTER_COUNT + j] = p->sRAMBases[i][j];
+            sRAMSizes[i * gcvSRAM_INTER_COUNT + j] = p->sRAMSizes[i][j];
         }
     }
 
-    sRAMMode = p->sRAMMode;
+    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+    {
+        extSRAMBases[i] = p->extSRAMBases[i];
+        extSRAMSizes[i] = p->extSRAMSizes[i];
+
+#if USE_LINUX_PCIE
+        sRAMBars[i]     = p->sRAMBars[i];
+        sRAMOffsets[i]  = p->sRAMOffsets[i];
+#endif
+    }
+
+    sRAMRequested = p->sRAMRequested;
+    sRAMLoopMode  = p->sRAMLoopMode;
 
     baseAddress = (ulong)p->baseAddress;
     physSize    = p->physSize;
@@ -479,7 +553,7 @@ gckOS_DumpParam(
 #if USE_LINUX_PCIE
     if (bar != -1)
     {
-        printk("  bar               = %d\n",     bar);
+        printk("  bar               = %d\n",      bar);
     }
 #endif
 #if gcdDEC_ENABLE_AHB
@@ -488,9 +562,17 @@ gckOS_DumpParam(
 #endif
 
     printk("  contiguousSize    = 0x%08lX\n", contiguousSize);
-    printk("  contiguousBase    = 0x%08lX\n", contiguousBase);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+    printk("  contiguousBase    = 0x%llX\n",  contiguousBase);
+#else
+    printk("  contiguousBase    = 0x%lX\n",  contiguousBase);
+#endif
     printk("  externalSize      = 0x%08lX\n", externalSize);
-    printk("  externalBase      = 0x%08lX\n", externalBase);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+    printk("  externalBase      = 0x%llX\n",  externalBase);
+#else
+    printk("  externalBase      = 0x%lX\n",  externalBase);
+#endif
     printk("  bankSize          = 0x%08lX\n", bankSize);
     printk("  fastClear         = %d\n",      fastClear);
     printk("  compression       = %d\n",      compression);
@@ -517,6 +599,14 @@ gckOS_DumpParam(
         printk("%d, ", bars[i]);
     }
     printk("\n");
+
+    printk("  regOffsets        = ");
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        printk("%d, ", regOffsets[i]);
+    }
+    printk("\n");
+
 #endif
     printk("  registerBases     = ");
     for (i = 0; i < gcvCORE_COUNT; i++)
@@ -541,15 +631,22 @@ gckOS_DumpParam(
 
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
-        printk("  core %d sRAMBases = ", i);
+        printk("  core %d internal sRAMBases = ", i);
 
-        for (j = 0; j < gcvSRAM_COUNT; j++)
+        for (j = 0; j < gcvSRAM_INTER_COUNT; j++)
         {
-            printk("0x%llX, ", sRAMBases[i * gcvSRAM_COUNT + j]);
+            printk("0x%llX, ", sRAMBases[i * gcvSRAM_INTER_COUNT + j]);
         }
         printk("\n");
     }
 
+    printk("  External sRAMBases = ");
+    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+    {
+        printk("0x%llx, ", extSRAMBases[i]);
+    }
+    printk("\n");
+
     printk("Build options:\n");
     printk("  gcdGPU_TIMEOUT    = %d\n", gcdGPU_TIMEOUT);
     printk("  gcdGPU_2D_TIMEOUT = %d\n", gcdGPU_2D_TIMEOUT);
@@ -576,8 +673,9 @@ static int drv_open(
         return -ENOMEM;
     }
 
-    data->device  = galDevice;
-    data->pidOpen = _GetProcessID();
+    data->isLocked = gcvFALSE;
+    data->device   = galDevice;
+    data->pidOpen  = _GetProcessID();
 
     /* Attached the process. */
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
@@ -605,7 +703,7 @@ static int drv_open(
                 gcmkVERIFY_OK(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvFALSE));
             }
         }
-
+        kfree(data);
         gcmkFOOTER_ARG("status=%d", status);
         return -ENOTTY;
     }
@@ -656,6 +754,13 @@ static int drv_release(
         gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
     }
 
+    if (data->isLocked)
+    {
+        /* Release the mutex. */
+        gcmkONERROR(gckOS_ReleaseMutex(gcvNULL, device->device->commitMutex));
+        data->isLocked = gcvFALSE;
+    }
+
     /* A process gets detached. */
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
@@ -781,6 +886,18 @@ static long drv_ioctl(
         gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
     }
 
+    if (iface.command == gcvHAL_DEVICE_MUTEX)
+    {
+        if (iface.u.DeviceMutex.isMutexLocked == gcvTRUE)
+        {
+            data->isLocked = gcvTRUE;
+        }
+        else
+        {
+            data->isLocked = gcvFALSE;
+        }
+    }
+
     status = gckDEVICE_Dispatch(device->device, &iface);
 
     /* Redo system call after pending signal is handled. */
@@ -840,7 +957,7 @@ static int drv_init(void)
 
     gcmkHEADER();
 
-    printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
+    printk("Galcore version %d.%d.%d.%d\n",
         gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
 
     if (showArgs)
@@ -986,13 +1103,17 @@ static void drv_exit(void)
     gcmkFOOTER_NO();
 }
 
+#if gcdENABLE_DRM
+int viv_drm_probe(struct device *dev);
+int viv_drm_remove(struct device *dev);
+#endif
 
-struct device *galcore_device;
+struct device *galcore_device = NULL;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
-int gpu_probe(struct platform_device *pdev)
+static int gpu_probe(struct platform_device *pdev)
 #else
-int __devinit gpu_probe(struct platform_device *pdev)
+static int __devinit gpu_probe(struct platform_device *pdev)
 #endif
 {
     int ret = -ENODEV;
@@ -1003,7 +1124,7 @@ int __devinit gpu_probe(struct platform_device *pdev)
 #endif
 
     gcmkHEADER();
-    if (get_nna_status(pdev) == 1)
+    if (get_nna_status(pdev) == gcvSTATUS_MISMATCH)
     {
         printk("nn is disable,should not do probe continue\n");
         return ret;
@@ -1041,6 +1162,10 @@ int __devinit gpu_probe(struct platform_device *pdev)
     if (!ret)
     {
         platform_set_drvdata(pdev, galDevice);
+
+#if gcdENABLE_DRM
+        ret = viv_drm_probe(&pdev->dev);
+#endif
     }
 
     if (ret < 0)
@@ -1057,13 +1182,17 @@ int __devinit gpu_probe(struct platform_device *pdev)
 }
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
-int gpu_remove(struct platform_device *pdev)
+static int gpu_remove(struct platform_device *pdev)
 #else
-int __devexit gpu_remove(struct platform_device *pdev)
+ static int __devexit gpu_remove(struct platform_device *pdev)
 #endif
 {
     gcmkHEADER();
 
+#if gcdENABLE_DRM
+    viv_drm_remove(&pdev->dev);
+#endif
+
     drv_exit();
 
     if (platform->ops->putPower)
@@ -1071,6 +1200,8 @@ int __devexit gpu_remove(struct platform_device *pdev)
         platform->ops->putPower(platform);
     }
 
+    galcore_device->dma_mask = NULL;
+    galcore_device = NULL;
     gcmkFOOTER_NO();
     return 0;
 }
@@ -1094,7 +1225,7 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state)
         {
             /* Store states. */
             {
-                status = gckHARDWARE_QueryPowerManagementState(device->kernels[i]->hardware, &device->statesStored[i]);
+                status = gckHARDWARE_QueryPowerState(device->kernels[i]->hardware, &device->statesStored[i]);
             }
 
             if (gcmIS_ERROR(status))
@@ -1103,7 +1234,7 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state)
             }
 
             {
-                status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
+                status = gckHARDWARE_SetPowerState(device->kernels[i]->hardware, gcvPOWER_OFF);
             }
 
             if (gcmIS_ERROR(status))
@@ -1136,7 +1267,7 @@ static int gpu_resume(struct platform_device *dev)
         if (device->kernels[i] != gcvNULL)
         {
             {
-                status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
+                status = gckHARDWARE_SetPowerState(device->kernels[i]->hardware, gcvPOWER_ON);
             }
 
             if (gcmIS_ERROR(status))
@@ -1166,7 +1297,7 @@ static int gpu_resume(struct platform_device *dev)
 
             /* Restore states. */
             {
-                status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored);
+                status = gckHARDWARE_SetPowerState(device->kernels[i]->hardware, statesStored);
             }
 
             if (gcmIS_ERROR(status))
@@ -1210,7 +1341,7 @@ static struct platform_driver gpu_driver = {
     .resume     = gpu_resume,
 
     .driver     = {
-        .owner  = THIS_MODULE,
+        .owner = THIS_MODULE,
         .name   = DEVICE_NAME,
 #if defined(CONFIG_PM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
         .pm     = &gpu_pm_ops,
@@ -1218,25 +1349,10 @@ static struct platform_driver gpu_driver = {
     }
 };
 
-#if gcdENABLE_DRM
-#if USE_LINUX_PCIE
-int viv_drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-void viv_drm_remove(struct pci_dev *pdev);
-#else
-int viv_drm_probe(struct platform_device *pdev);
-int viv_drm_remove(struct platform_device *pdev);
-#endif
-#endif
-
 static int __init gpu_init(void)
 {
     int ret = 0;
 
-#if gcdENABLE_DRM
-    gpu_driver.probe = viv_drm_probe;
-    gpu_driver.remove = viv_drm_remove;
-#endif
-
     ret = gckPLATFORM_Init(&gpu_driver, &platform);
 
     if (ret || !platform)
index 2b86deb055ad015b75fa5a2c62c9d5340f31c192..23d0f4c5e8786125559b286dbf9f03b04e8ccb25 100644 (file)
 #include <drm/drmP.h>
 #include <drm/drm_gem.h>
 #include <linux/dma-buf.h>
-#include <linux/component.h>
 #include "gc_hal_kernel_linux.h"
 #include "gc_hal_drm.h"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
-#error "Vivante DRM is NOT supportted on linux kernel early than 3.8.0"
-#endif
-
 #define _GC_OBJ_ZONE    gcvZONE_KERNEL
 
 /******************************************************************************\
@@ -77,6 +72,7 @@ struct viv_gem_object {
 
     uint32_t              node_handle;
     gckVIDMEM_NODE        node_object;
+    gctBOOL               cacheable;
 };
 
 struct dma_buf *viv_gem_prime_export(struct drm_device *drm,
@@ -90,7 +86,7 @@ struct dma_buf *viv_gem_prime_export(struct drm_device *drm,
     if (gal_dev)
     {
         gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
-        gcmkVERIFY_OK(gckVIDMEM_NODE_Export(kernel, viv_obj->node_handle, flags,
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Export(kernel, viv_obj->node_object, flags,
                                             (gctPOINTER*)&dmabuf, gcvNULL));
     }
 
@@ -172,6 +168,7 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data,
     gckVIDMEM_NODE nodeObject;
     gctUINT32 flags = gcvALLOC_FLAG_DMABUF_EXPORTABLE;
     gceSTATUS status = gcvSTATUS_OK;
+    gctUINT64 alignSize = PAGE_ALIGN(args->size);
 
     gal_dev = (gckGALDEVICE)drm->dev_private;
     if (!gal_dev)
@@ -195,7 +192,7 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data,
     gckOS_ZeroMemory(&iface, sizeof(iface));
     iface.command = gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY;
     iface.hardwareType = gal_dev->device->defaultHwType;
-    iface.u.AllocateLinearVideoMemory.bytes = PAGE_ALIGN(args->size);
+    iface.u.AllocateLinearVideoMemory.bytes = alignSize;
     iface.u.AllocateLinearVideoMemory.alignment = 256;
     iface.u.AllocateLinearVideoMemory.type = gcvVIDMEM_TYPE_GENERIC;
     iface.u.AllocateLinearVideoMemory.flag = flags;
@@ -208,12 +205,13 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data,
 
     /* ioctl output */
     gem_obj = kzalloc(sizeof(struct viv_gem_object), GFP_KERNEL);
-    drm_gem_private_object_init(drm, gem_obj, (size_t)iface.u.AllocateLinearVideoMemory.bytes);
+    drm_gem_private_object_init(drm, gem_obj, (size_t)alignSize);
     ret = drm_gem_handle_create(file, gem_obj, &args->handle);
 
     viv_obj = container_of(gem_obj, struct viv_gem_object, base);
     viv_obj->node_handle = iface.u.AllocateLinearVideoMemory.node;
     viv_obj->node_object = nodeObject;
+    viv_obj->cacheable = flags & gcvALLOC_FLAG_CACHEABLE;
 
     /* drop reference from allocate - handle holds it now */
     drm_gem_object_unreference_unlocked(gem_obj);
@@ -552,6 +550,16 @@ static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data,
     {
         struct viv_gem_object *viv_ts_obj;
         gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
+        gcsHAL_INTERFACE iface;
+        gctBOOL is128BTILE = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_128BTILE);
+        gctBOOL is2BitPerTile = is128BTILE ? gcvFALSE : gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_TILE_STATUS_2BITS);
+        gctBOOL isCompressionDEC400 = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_COMPRESSION_DEC400);
+        gctPOINTER entry = gcvNULL;
+        gckVIDMEM_NODE ObjNode = gcvNULL;
+        gctUINT32 processID = 0;
+        gctUINT32 tileStatusFiller = (isCompressionDEC400 || ((kernel->hardware->identity.chipModel == gcv500) && (kernel->hardware->identity.chipRevision > 2)))
+                                  ? 0xFFFFFFFF
+                                  : is2BitPerTile ? 0x55555555 : 0x11111111;
 
         gem_ts_obj = drm_gem_object_lookup(file, args->ts_handle);
         if (!gem_ts_obj)
@@ -562,6 +570,38 @@ static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data,
 
         gcmkONERROR(gckVIDMEM_NODE_Reference(kernel, viv_ts_obj->node_object));
         nodeObj->tsNode = viv_ts_obj->node_object;
+
+        /* Fill tile status node with tileStatusFiller value first time to avoid GPU hang. */
+        /* Lock tile status node. */
+        gckOS_ZeroMemory(&iface, sizeof(iface));
+        iface.command = gcvHAL_LOCK_VIDEO_MEMORY;
+        iface.hardwareType = gal_dev->device->defaultHwType;
+        iface.u.LockVideoMemory.node = viv_ts_obj->node_handle;
+        iface.u.LockVideoMemory.cacheable = viv_ts_obj->cacheable;
+        gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+        gcmkONERROR(gckOS_GetProcessID(&processID));
+        gcmkONERROR(gckVIDMEM_HANDLE_Lookup(kernel, processID, viv_ts_obj->node_handle, &ObjNode));
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(kernel, ObjNode, gcvFALSE, gcvFALSE, &entry));
+
+        /* Fill tile status node with tileStatusFiller. */
+        memset(entry , tileStatusFiller , (__u64)gem_ts_obj->size);
+        gcmkONERROR(gckVIDMEM_NODE_UnlockCPU(kernel, ObjNode, 0, gcvFALSE));
+
+        /* UnLock tile status node. */
+        memset(&iface, 0, sizeof(iface));
+        iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
+        iface.hardwareType = gal_dev->device->defaultHwType;
+        iface.u.UnlockVideoMemory.node = (gctUINT64)viv_ts_obj->node_handle;
+        iface.u.UnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+        gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
+
+        memset(&iface, 0, sizeof(iface));
+        iface.command = gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY;
+        iface.hardwareType = gal_dev->device->defaultHwType;
+        iface.u.BottomHalfUnlockVideoMemory.node = (gctUINT64)viv_ts_obj->node_handle;
+        iface.u.BottomHalfUnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+        gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
     }
 
 OnError:
@@ -723,7 +763,9 @@ static const struct file_operations viv_drm_fops = {
     .open               = drm_open,
     .release            = drm_release,
     .unlocked_ioctl     = drm_ioctl,
+#ifdef CONFIG_COMPAT
     .compat_ioctl       = drm_compat_ioctl,
+#endif
     .poll               = drm_poll,
     .read               = drm_read,
     .llseek             = no_llseek,
@@ -752,43 +794,20 @@ static struct drm_driver viv_drm_driver = {
     .minor              = 0,
 };
 
-#if USE_LINUX_PCIE
-int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-void gpu_remove(struct pci_dev *pdev);
-#else
-int gpu_probe(struct platform_device *pdev);
-int gpu_remove(struct platform_device *pdev);
-#endif
-
-static int viv_drm_bind(struct device *dev)
+int viv_drm_probe(struct device *dev)
 {
-    int ret;
+    int ret = 0;
     gceSTATUS status = gcvSTATUS_OK;
     gckGALDEVICE gal_dev = gcvNULL;
     struct drm_device *drm = gcvNULL;
 
-    ret = component_bind_all(dev, 0);
-    if (ret)
-    {
-        gcmkONERROR(gcvSTATUS_GENERIC_IO);
-    }
-
-#if USE_LINUX_PCIE
-    ret = gpu_probe(to_pci_dev(dev), gcvNULL);
-#else
-    ret = gpu_probe(to_platform_device(dev));
-#endif
-    if (ret)
-    {
-        gcmkONERROR(gcvSTATUS_GENERIC_IO);
-    }
-
-    gal_dev = (gckGALDEVICE)platform_get_drvdata(to_platform_device(dev));
+    gal_dev = (gckGALDEVICE)dev_get_drvdata(dev);
     if (!gal_dev)
     {
         ret = -ENODEV;
         gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
     }
+
     drm = drm_dev_alloc(&viv_drm_driver, dev);
     if (IS_ERR(drm))
     {
@@ -812,13 +831,12 @@ OnError:
         {
             drm_dev_unref(drm);
         }
-        component_unbind_all(dev, 0);
         printk(KERN_ERR "galcore: Failed to setup drm device.\n");
     }
     return ret;
 }
 
-static void viv_drm_unbind(struct device *dev)
+int viv_drm_remove(struct device *dev)
 {
     gckGALDEVICE gal_dev = (gckGALDEVICE)dev_get_drvdata(dev);
 
@@ -830,66 +848,7 @@ static void viv_drm_unbind(struct device *dev)
         drm_dev_unref(drm);
     }
 
-#if USE_LINUX_PCIE
-    gpu_remove(to_pci_dev(dev));
-#else
-    gpu_remove(to_platform_device(dev));
-#endif
-
-    component_unbind_all(dev, 0);
-}
-
-static const struct component_master_ops viv_master_ops =
-{
-    .bind   = viv_drm_bind,
-    .unbind = viv_drm_unbind,
-};
-
-static int viv_compare_of(struct device *dev, void *data)
-{
-    struct device_node *np = data;
-
-    return dev->of_node == np;
-}
-
-int viv_drm_probe (
-#if USE_LINUX_PCIE
-    struct pci_dev *pdev,
-    const struct pci_device_id *ent
-#else
-    struct platform_device *pdev
-#endif
-    )
-{
-    int i = 0;
-    struct component_match *match = NULL;
-    struct device_node * node = pdev->dev.of_node;
-    struct device_node *core_node;
-
-    /* Below code snippet shall be moved to gc_hal_kernel_platform_imx6.c */
-    while ((core_node = of_parse_phandle(node, "cores", i++)) != NULL) {
-        if (of_device_is_available(core_node)) {
-            component_match_add(&pdev->dev, &match, viv_compare_of, core_node);
-        }
-
-        of_node_put(core_node);
-    }
-    /* Above code snippet shall be moved to gc_hal_kernel_platform_imx6.c */
-
-    return component_master_add_with_match(&pdev->dev, &viv_master_ops, match);
-}
-
-#if USE_LINUX_PCIE
-void viv_drm_remove(struct pci_dev *pdev)
-#else
-int  viv_drm_remove(struct platform_device *pdev)
-#endif
-{
-    component_master_del(&pdev->dev, &viv_master_ops);
-
-#if !USE_LINUX_PCIE
     return 0;
-#endif
 }
 
 #endif
index 3b72a6643a310927a6681024348c86f98dc05f76..343f0f7d87e33a90237070cc5fcf82a20dcaa8f9 100644 (file)
@@ -169,9 +169,14 @@ gckKERNEL_GetVideoMemoryPool(
         videoMemory = device->contiguousVidMem;
         break;
 
-    case gcvPOOL_SRAM:
-        /* SRAM memory. */
-        videoMemory = Kernel->sRAMVideoMem[Kernel->sRAMIndex];
+    case gcvPOOL_INTERNAL_SRAM:
+        /* Internal SRAM memory. */
+        videoMemory = Kernel->sRAMVidMem[Kernel->sRAMIndex];
+        break;
+
+    case gcvPOOL_EXTERNAL_SRAM:
+        /* External SRAM memory. */
+        videoMemory = device->extSRAMVidMem[Kernel->extSRAMIndex];
         break;
 
     default:
@@ -338,12 +343,29 @@ gckKERNEL_MapVideoMemory(
         bytes = device->contiguousSize;
         break;
 
-    case gcvPOOL_SRAM:
-        /* SRAM memory. */
-        physHandle = (PLINUX_MDL)Kernel->sRAMPhysical[Kernel->sRAMIndex];
-        bytes = Kernel->sRAMSizes[Kernel->sRAMIndex];
+    case gcvPOOL_EXTERNAL_SRAM:
+        /* External shared SRAM memory. */
+        physHandle = (PLINUX_MDL)device->extSRAMPhysical[Kernel->extSRAMIndex];
+        bytes = device->extSRAMSizes[Kernel->extSRAMIndex];
         break;
 
+    case gcvPOOL_INTERNAL_SRAM:
+        /* Per core SRAM reserved usage. */
+        if (Kernel->sRAMPhysFaked[Kernel->sRAMIndex])
+        {
+            *Logical = gcvNULL;
+
+            gcmkFOOTER_NO();
+            return gcvSTATUS_OK;
+        }
+        /* Per core SRAM memory block. */
+        else
+        {
+            physHandle = (PLINUX_MDL)Kernel->sRAMPhysical[Kernel->sRAMIndex];
+            bytes = Kernel->sRAMSizes[Kernel->sRAMIndex];
+            break;
+        }
+
     default:
         /* Invalid memory pool. */
         gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
index 7144e6756d5aa441fc32471fc0354bce0de7028e..bfad0c58c02ef79a5b195e689e1bbafd5c58289b 100644 (file)
 #  include <linux/modversions.h>
 #endif
 #include <asm/io.h>
-#include <asm/uaccess.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(4,7,0)
+    #include <linux/uaccess.h>
+#else
+    #include <asm/uaccess.h>
+#endif
 
 #if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
 #include <linux/clk.h>
 #  define dma_fence_context_alloc(s)        fence_context_alloc(s)
 
 #endif
-int get_nna_status(struct platform_device *dev);
+
+gceSTATUS get_nna_status(struct platform_device *dev);
+
 extern struct device *galcore_device;
 
 /******************************************************************************\
@@ -168,31 +174,6 @@ extern struct device *galcore_device;
 \******************************************************************************/
 typedef struct _gcsIOMMU * gckIOMMU;
 
-#if gcdSECURE_USER
-typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
-typedef struct _gcsUSER_MAPPING
-{
-    /* Pointer to next mapping structure. */
-    gcsUSER_MAPPING_PTR         next;
-
-    /* Physical address of this mapping. */
-    gctUINT32                   physical;
-
-    /* Logical address of this mapping. */
-    gctPOINTER                  logical;
-
-    /* Number of bytes of this mapping. */
-    gctSIZE_T                   bytes;
-
-    /* Starting address of this mapping. */
-    gctINT8_PTR                 start;
-
-    /* Ending address of this mapping. */
-    gctINT8_PTR                 end;
-}
-gcsUSER_MAPPING;
-#endif
-
 typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
 typedef struct _gcsINTEGER_DB
 {
@@ -220,15 +201,11 @@ struct _gckOS
     /* Signal management. */
 
     /* Lock. */
-    struct mutex                signalMutex;
+    spinlock_t                  signalLock;
 
     /* signal id database. */
     gcsINTEGER_DB               signalDB;
 
-#if gcdSECURE_USER
-    gcsUSER_MAPPING_PTR         userMap;
-#endif
-
     /* workqueue for os timer. */
     struct workqueue_struct *   workqueue;
 
index cea4a5d0b56c097027bc138eb1936b969cc410ed..1e073c90f938582589bd554e7610311d22a6c75c 100644 (file)
@@ -695,8 +695,8 @@ gckOS_Construct(
      * Initialize the signal manager.
      */
 
-    /* Initialize mutex. */
-    mutex_init(&os->signalMutex);
+    /* Initialize spinlock. */
+    spin_lock_init(&os->signalLock);
 
     /* Initialize signal id database lock. */
     spin_lock_init(&os->signalDB.lock);
@@ -1424,6 +1424,7 @@ gckOS_AllocateNonPagedMemory(
     gcmkONERROR(status);
 
     mdl->cacheable = Flag & gcvALLOC_FLAG_CACHEABLE;
+
     mdl->bytes    = bytes;
     mdl->numPages = numPages;
 
@@ -1431,8 +1432,11 @@ gckOS_AllocateNonPagedMemory(
 
     gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, 0, bytes, &addr));
 
-    /* Trigger a page fault. */
-    memset(addr, 0, numPages * PAGE_SIZE);
+    if (!strcmp(allocator->name, "gfp"))
+    {
+        /* Trigger a page fault. */
+        memset(addr, 0, numPages * PAGE_SIZE);
+    }
 
     mdl->addr = addr;
 
@@ -2107,83 +2111,6 @@ gceSTATUS gckOS_UserLogicalToPhysical(
     return gckOS_GetPhysicalAddress(Os, Logical, Address);
 }
 
-#if gcdSECURE_USER
-static gceSTATUS
-gckOS_AddMapping(
-    IN gckOS Os,
-    IN gctUINT32 Physical,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcsUSER_MAPPING_PTR map;
-
-    gcmkHEADER_ARG("Os=%p Physical=0x%x Logical=%p Bytes=0x%zx",
-                   Os, Physical, Logical, Bytes);
-
-    gcmkONERROR(gckOS_Allocate(Os,
-                               gcmSIZEOF(gcsUSER_MAPPING),
-                               (gctPOINTER *) &map));
-
-    map->next     = Os->userMap;
-    map->physical = Physical - Os->device->baseAddress;
-    map->logical  = Logical;
-    map->bytes    = Bytes;
-    map->start    = (gctINT8_PTR) Logical;
-    map->end      = map->start + Bytes;
-
-    Os->userMap = map;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-static gceSTATUS
-gckOS_RemoveMapping(
-    IN gckOS Os,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcsUSER_MAPPING_PTR map, prev;
-
-    gcmkHEADER_ARG("Os=%p Logical=%p Bytes=0x%zx", Os, Logical, Bytes);
-
-    for (map = Os->userMap, prev = gcvNULL; map != gcvNULL; map = map->next)
-    {
-        if ((map->logical == Logical) && (map->bytes == Bytes))
-        {
-            break;
-        }
-
-        prev = map;
-    }
-
-    if (map == gcvNULL)
-    {
-        gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
-    }
-
-    if (prev == gcvNULL)
-    {
-        Os->userMap = map->next;
-    }
-    else
-    {
-        prev->next = map->next;
-    }
-
-    gcmkONERROR(gcmkOS_SAFE_FREE(Os, map));
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
 gceSTATUS
 _ConvertLogical2Physical(
     IN gckOS Os,
@@ -3075,7 +3002,7 @@ gckOS_GetTime(
 
     /* Return the time of day in microseconds. */
     ktime_get_real_ts64(&tv);
-    *Time = (tv.tv_sec * 1000000ULL) + (tv.tv_nsec * 1000);
+    *Time = (tv.tv_sec * 1000000ULL) + (tv.tv_nsec / 1000);
 #else
     struct timeval tv;
     gcmkHEADER();
@@ -3162,6 +3089,7 @@ gckOS_AllocatePagedMemory(
     gctSIZE_T bytes;
     gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
     gckALLOCATOR allocator;
+    gctBOOL zoneDMA32 = gcvFALSE;
 
     gcmkHEADER_ARG("Os=%p Flag=%x *Bytes=0x%zx", Os, Flag, *Bytes);
 
@@ -3180,6 +3108,17 @@ gckOS_AllocatePagedMemory(
         gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
     }
 
+#if defined(CONFIG_ZONE_DMA32)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+    zoneDMA32 = gcvTRUE;
+#endif
+#endif
+
+    if ((Flag & gcvALLOC_FLAG_4GB_ADDR) && !zoneDMA32)
+    {
+        Flag &= ~gcvALLOC_FLAG_4GB_ADDR;
+    }
+
     /* Walk all allocators. */
     list_for_each_entry(allocator, &Os->allocatorList, link)
     {
@@ -3365,15 +3304,11 @@ gckOS_LockPages(
     /* Convert pointer to MDL. */
     *Logical = mdlMap->vmaAddr;
 
-    /* Return the page number according to the GPU page size. */
-    gcmkASSERT((PAGE_SIZE % 4096) == 0);
-    gcmkASSERT((PAGE_SIZE / 4096) >= 1);
-
 OnError:
     mutex_unlock(&mdl->mapsMutex);
     /* Success. */
     gcmkFOOTER_ARG("*Logical=%p", *Logical);
-    return gcvSTATUS_OK;
+    return status;
 }
 
 /* PageCount is GPU page count. */
@@ -3490,6 +3425,7 @@ gckOS_MapPagesEx(
                     gcmkONERROR(
                         gckMMU_SetPage(Os->device->kernels[Core]->mmu,
                             phys + (i * 4096),
+                            gcvPAGE_TYPE_4K,
                             Writable,
                             table++));
                 }
@@ -3501,7 +3437,7 @@ gckOS_MapPagesEx(
 
     {
         gckMMU mmu = Os->device->kernels[Core]->mmu;
-        gcsADDRESS_AREA * area = &mmu->dynamicArea;
+        gcsADDRESS_AREA * area = &mmu->dynamicArea4K;
 
         offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)area->stlbLogical;
 
@@ -3554,6 +3490,135 @@ gckOS_UnmapPages(
     return gcvSTATUS_OK;
 }
 
+/* Map 1M size GPU page */
+gceSTATUS
+gckOS_Map1MPages(
+    IN gckOS Os,
+    IN gceCORE Core,
+    IN gctPHYS_ADDR Physical,
+    IN gctSIZE_T PageCount,
+    IN gctUINT32 Address,
+    IN gctPOINTER PageTable,
+    IN gctBOOL Writable,
+    IN gceVIDMEM_TYPE Type
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    PLINUX_MDL mdl;
+    gctUINT32* table;
+    gctUINT32  offset = 0;
+
+    gctSIZE_T bytes = PageCount * 4;
+    gckALLOCATOR allocator;
+
+    gctUINT32 policyID = 0;
+    gctUINT32 axiConfig = 0;
+
+    gcsPLATFORM * platform = Os->device->platform;
+
+    gcmkHEADER_ARG("Os=%p Core=%d Physical=%p PageCount=0x%zx Address=0x%x PageTable=%p",
+                   Os, Core, Physical, PageCount, Address, PageTable);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+    gcmkVERIFY_ARGUMENT(PageCount > 0);
+    gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
+
+    /* Convert pointer to MDL. */
+    mdl = (PLINUX_MDL)Physical;
+
+    allocator = mdl->allocator;
+
+    gcmkASSERT(allocator != gcvNULL);
+
+    gcmkTRACE_ZONE(
+        gcvLEVEL_INFO, gcvZONE_OS,
+        "%s(%d): Physical->0x%X PageCount->0x%X",
+        __FUNCTION__, __LINE__,
+        (gctUINT32)(gctUINTPTR_T)Physical,
+        (gctUINT32)(gctUINTPTR_T)PageCount
+        );
+
+    table = (gctUINT32 *)PageTable;
+
+    if (platform && platform->ops->getPolicyID)
+    {
+        platform->ops->getPolicyID(platform, Type, &policyID, &axiConfig);
+
+        gcmkBUG_ON(policyID > 0x1F);
+
+        /* ID[3:0] is used in STLB. */
+        policyID &= 0xF;
+    }
+
+    while (PageCount-- > 0)
+    {
+        gctPHYS_ADDR_T phys = ~0U;
+
+        allocator->ops->Physical(allocator, mdl, offset, &phys);
+
+        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
+
+        if (policyID)
+        {
+            /* AxUSER must not used for address currently. */
+            gcmkBUG_ON((phys >> 32) & 0xF);
+
+            /* Merge policyID to AxUSER[7:4].*/
+            phys |= ((gctPHYS_ADDR_T)policyID << 36);
+        }
+
+        /* Get the start physical of 1M page. */
+        phys &= ~((1 << 20) - 1);
+
+        gcmkONERROR(
+            gckMMU_SetPage(Os->device->kernels[Core]->mmu,
+            phys,
+            gcvPAGE_TYPE_1M,
+            Writable,
+            table++));
+
+        offset += gcd1M_PAGE_SIZE;
+    }
+
+    /* Flush the page table cache. */
+    {
+        gckMMU mmu = Os->device->kernels[Core]->mmu;
+        gcsADDRESS_AREA * area = &mmu->dynamicArea1M;
+
+        offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)area->stlbLogical;
+
+        /* must be in dynamic area. */
+        gcmkASSERT(offset < area->stlbSize);
+
+        gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+            Os->device->kernels[Core],
+            area->stlbVideoMem,
+            offset,
+            PageTable,
+            bytes
+            ));
+
+        if (mmu->mtlbVideoMem)
+        {
+            /* Flush MTLB table. */
+            gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+                Os->device->kernels[Core],
+                mmu->mtlbVideoMem,
+                offset,
+                mmu->mtlbLogical,
+                mmu->mtlbSize
+                ));
+        }
+    }
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
 /*******************************************************************************
 **
 **  gckOS_UnlockPages
@@ -4378,8 +4443,8 @@ gckOS_Broadcast(
 
         /* Put GPU OFF. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Hardware,
-                                                gcvPOWER_OFF_BROADCAST));
+            gckHARDWARE_SetPowerState(Hardware,
+                                      gcvPOWER_OFF_BROADCAST));
         break;
 
     case gcvBROADCAST_GPU_IDLE:
@@ -4392,7 +4457,7 @@ gckOS_Broadcast(
 
         /* Put GPU IDLE or SUSPEND. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Hardware, state));
+            gckHARDWARE_SetPowerState(Hardware, state));
 
         /* Add idle process DB. */
         gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
@@ -4412,7 +4477,7 @@ gckOS_Broadcast(
 
         /* Put GPU ON. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON_AUTO));
+            gckHARDWARE_SetPowerState(Hardware, gcvPOWER_ON_AUTO));
         break;
 
     case gcvBROADCAST_GPU_STUCK:
@@ -5260,6 +5325,7 @@ gckOS_DestroySignal(
     gceSTATUS status = gcvSTATUS_OK;
     gcsSIGNAL_PTR signal;
     gctBOOL acquired = gcvFALSE;
+    unsigned long flags = 0;
 
     gcmkHEADER_ARG("Os=%p Signal=%p", Os, Signal);
 
@@ -5267,7 +5333,11 @@ gckOS_DestroySignal(
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
 
-    mutex_lock(&Os->signalMutex);
+    if(in_irq()){
+        spin_lock(&Os->signalLock);
+    }else{
+        spin_lock_irqsave(&Os->signalLock, flags);
+    }
     acquired = gcvTRUE;
 
     gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
@@ -5282,14 +5352,22 @@ gckOS_DestroySignal(
         kfree(signal);
     }
 
-    mutex_unlock(&Os->signalMutex);
+    if(in_irq()){
+        spin_unlock(&Os->signalLock);
+    }else{
+        spin_unlock_irqrestore(&Os->signalLock, flags);
+    }
     acquired = gcvFALSE;
 
 OnError:
     if (acquired)
     {
         /* Release the mutex. */
-        mutex_unlock(&Os->signalMutex);
+        if(in_irq()){
+            spin_unlock(&Os->signalLock);
+        }else{
+            spin_unlock_irqrestore(&Os->signalLock, flags);
+        }
     }
 
     gcmkFOOTER();
@@ -5334,6 +5412,7 @@ gckOS_Signal(
     struct dma_fence * fence = gcvNULL;
 #  endif
 #endif
+    unsigned long flags = 0;
 
     gcmkHEADER_ARG("Os=%p Signal=%p State=%d", Os, Signal, State);
 
@@ -5341,7 +5420,7 @@ gckOS_Signal(
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
 
-    mutex_lock(&Os->signalMutex);
+    spin_lock_irqsave(&Os->signalLock, flags);
 
     status = _QueryIntegerId(&Os->signalDB,
                              (gctUINT32)(gctUINTPTR_T)Signal,
@@ -5349,7 +5428,7 @@ gckOS_Signal(
 
     if (gcmIS_ERROR(status))
     {
-        mutex_unlock(&Os->signalMutex);
+        spin_unlock_irqrestore(&Os->signalLock, flags);
         gcmkONERROR(status);
     }
 
@@ -5360,7 +5439,7 @@ gckOS_Signal(
      */
     atomic_inc(&signal->ref);
 
-    mutex_unlock(&Os->signalMutex);
+    spin_unlock_irqrestore(&Os->signalLock, flags);
 
     gcmkONERROR(status);
 
@@ -5406,7 +5485,7 @@ gckOS_Signal(
 #  endif
 #endif
 
-    mutex_lock(&Os->signalMutex);
+    spin_lock_irqsave(&Os->signalLock, flags);
 
     if (atomic_dec_and_test(&signal->ref))
     {
@@ -5416,7 +5495,7 @@ gckOS_Signal(
         kfree(signal);
     }
 
-    mutex_unlock(&Os->signalMutex);
+    spin_unlock_irqrestore(&Os->signalLock, flags);
 
 OnError:
     gcmkFOOTER();
@@ -5636,12 +5715,13 @@ gckOS_MapSignal(
 {
     gceSTATUS status = gcvSTATUS_OK;
     gcsSIGNAL_PTR signal = gcvNULL;
+    unsigned long flags = 0;
     gcmkHEADER_ARG("Os=%p Signal=%p Process=%p", Os, Signal, Process);
 
     gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
     gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
 
-    mutex_lock(&Os->signalMutex);
+    spin_lock_irqsave(&Os->signalLock, flags);
 
     gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
 
@@ -5654,7 +5734,7 @@ gckOS_MapSignal(
     *MappedSignal = (gctSIGNAL) Signal;
 
 OnError:
-    mutex_unlock(&Os->signalMutex);
+    spin_unlock_irqrestore(&Os->signalLock, flags);
 
     gcmkFOOTER_ARG("*MappedSignal=%p", *MappedSignal);
     return status;
@@ -6474,10 +6554,12 @@ OnError:
         fput(sync->file);
     }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,68)
     if (fence)
     {
         dma_fence_put(fence);
     }
+#endif
 
     if (fd > 0)
     {
@@ -6618,8 +6700,7 @@ gckOS_WaitNativeFence(
     {
         struct dma_fence *f = fences[i];
 
-        if (f->context != timeline->context &&
-            !dma_fence_is_signaled(f))
+        if(!dma_fence_is_signaled(fence))
         {
             signed long ret;
             ret = dma_fence_wait_timeout(f, 1, timeout);
@@ -6884,15 +6965,31 @@ gckOS_QueryOption(
     }
     else if (!strcmp(Option, "sRAMBases"))
     {
-        memcpy(Value, device->args.sRAMBases, gcmSIZEOF(gctUINT64) * gcvSRAM_COUNT * gcvCORE_COUNT);
+        memcpy(Value, device->args.sRAMBases, gcmSIZEOF(gctUINT64) * gcvSRAM_INTER_COUNT * gcvCORE_COUNT);
     }
     else if (!strcmp(Option, "sRAMSizes"))
     {
-        memcpy(Value, device->args.sRAMSizes, gcmSIZEOF(gctUINT32) * gcvSRAM_COUNT * gcvCORE_COUNT);
+        memcpy(Value, device->args.sRAMSizes, gcmSIZEOF(gctUINT32) * gcvSRAM_INTER_COUNT * gcvCORE_COUNT);
+    }
+    else if (!strcmp(Option, "extSRAMBases"))
+    {
+        memcpy(Value, device->args.extSRAMBases, gcmSIZEOF(gctUINT64) * gcvSRAM_EXT_COUNT);
+    }
+    else if (!strcmp(Option, "extSRAMSizes"))
+    {
+        memcpy(Value, device->args.extSRAMSizes, gcmSIZEOF(gctUINT32) * gcvSRAM_EXT_COUNT);
+    }
+    else if (!strcmp(Option, "sRAMRequested"))
+    {
+        *Value = device->args.sRAMRequested;
+    }
+    else if (!strcmp(Option, "sRAMLoopMode"))
+    {
+        *Value = device->args.sRAMLoopMode;
     }
-    else if (!strcmp(Option, "sRAMMode"))
+    else if (!strcmp(Option, "platformFlagBits"))
     {
-        *Value = device->args.sRAMMode;
+        *Value = device->platform->flagBits;
     }
     else
     {
@@ -7035,14 +7132,6 @@ gckOS_WrapMemory(
 
     if (Desc->flag & gcvALLOC_FLAG_DMABUF)
     {
-        if (IS_ERR(gcmUINT64_TO_PTR(Desc->dmabuf)))
-        {
-            /* Won't enter here currently, the caller confirms the dmabuf is valid. */
-
-            gcmkPRINT("Wrap memory: invalid dmabuf.\n");
-            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-        }
-
         desc.dmaBuf.dmabuf = gcmUINT64_TO_PTR(Desc->dmabuf);
 
 #if defined(CONFIG_DMA_SHARED_BUFFER)
index 358e2f0efbc3fbdfabdd46b9d592ea282fafc09a..baa5c9cbdc18ce056cd542207641ee9437e0588b 100644 (file)
@@ -102,6 +102,8 @@ struct _LINUX_MDL
     uint                    gid;
 
     struct list_head        link;
+
+    gctBOOL                 pageUnit1M;
 };
 
 extern PLINUX_MDL_MAP
index baf053406623bc64a4c042ffae084de6f8878475..0dba8f1b8e4532c52b1e4651c0e3251b55c012d9 100644 (file)
@@ -81,10 +81,21 @@ typedef struct _gcsMODULE_PARAMETERS
     gctPHYS_ADDR_T          externalBase;
     gctSIZE_T               externalSize;
 
-    /* SRAM. */
-    gctPHYS_ADDR_T          sRAMBases[gcvCORE_COUNT][gcvSRAM_COUNT];
-    gctUINT32               sRAMSizes[gcvCORE_COUNT][gcvSRAM_COUNT];
-    gctUINT32               sRAMMode;
+    /* Per-core SRAM. */
+    gctPHYS_ADDR_T          sRAMBases[gcvCORE_COUNT][gcvSRAM_INTER_COUNT];
+    gctUINT32               sRAMSizes[gcvCORE_COUNT][gcvSRAM_INTER_COUNT];
+
+    /* Shared SRAM. */
+    gctPHYS_ADDR_T          extSRAMBases[gcvSRAM_EXT_COUNT];
+    gctUINT32               extSRAMSizes[gcvSRAM_EXT_COUNT];
+#if USE_LINUX_PCIE
+    gctUINT32               regOffsets[gcvCORE_COUNT];
+    gctINT32                sRAMBars[gcvSRAM_EXT_COUNT];
+    gctINT32                sRAMOffsets[gcvSRAM_EXT_COUNT];
+#endif
+
+    gctBOOL                 sRAMRequested;
+    gctUINT32               sRAMLoopMode;
 
     gctPHYS_ADDR_T          baseAddress;
     gctSIZE_T               physSize;
@@ -283,6 +294,12 @@ struct _gcsPLATFORM
     const char *name;
     gcsPLATFORM_OPERATIONS* ops;
 
+    /* TODO: Remove AXI-SRAM size from feature database. */
+    gckDEVICE dev;
+
+    /* PLATFORM specific flags */
+    gctUINT32  flagBits;
+
     void*                   priv;
 };
 
index 89a4822e1b5825fe67aa814afc7f82f44dde42b4..c1367bcefb7c9052408a2c2f0eadb19307d3e3c7 100644 (file)
@@ -349,7 +349,10 @@ struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
 
     if (!signal->done) {
         signal->fence = (struct dma_fence*)fence;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,68)
         dma_fence_get((struct dma_fence*)fence);
+#endif
     }
 
     spin_unlock(&signal->lock);
index ed798abce1f69dd72c311daa70cb9491cad059e3..b322733e5a7952e2aa35e2fe78c3ec33cb580774 100644 (file)
 
 #include <linux/io.h>
 #include <linux/kernel.h>
-#include <dt-bindings/clock/amlogic,g12a-clkc.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/of_reserved_mem.h>
-#include <linux/cma.h>
-#include <linux/dma-contiguous.h>
 #include <linux/delay.h>
 
 #include "gc_hal_kernel_linux.h"
 #include "gc_hal_kernel_platform.h"
 
-/*======== add by zxw for g12b hardware reg begin ===========*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+#include <dt-bindings/clock/g12a-clkc.h>
+#else
+#include <dt-bindings/clock/amlogic,g12a-clkc.h>
+#endif
+
+/*======== power version 0 hardware reg begin ===========*/
 #define AO_RTI_BASE           0xff800000
-#define AO_RTI_GEN_PWR_SLEEP0 (AO_RTI_BASE + (0x3a<<2))   //0xff8000e8
-#define AO_RTI_GEN_PWR_ISO0   (AO_RTI_BASE + (0x3b<<2))   //0xff8000ec
+#define AO_RTI_GEN_PWR_SLEEP0 (AO_RTI_BASE + (0x3a<<2))
+#define AO_RTI_GEN_PWR_ISO0   (AO_RTI_BASE + (0x3b<<2))
+
+
+/*======== power version 1 hardware reg begin ===========*/
+#define P_PWRCTRL_ISO_EN1      0xfe007818
+#define P_PWRCTRL_PWR_OFF1     0xfe00781c
 
-#define HHI_BASE_ADDR         0xff63c000
-#define NN_CHIP_W400         0
-#define NN_CHIP_SM1         1
+static uint32_t HHI_NANOQ_MEM_PD_REG0 = 0xff63c10c;
+static uint32_t HHI_NANOQ_MEM_PD_REG1 = 0xff63c110;
+static  uint32_t RESET_LEVEL2 = 0xffd01088;
 
-static unsigned int HHI_NANOQ_MEM_PD_REG0 = HHI_BASE_ADDR+(0x43<<2);//0xff63c10c;
-static unsigned int HHI_NANOQ_MEM_PD_REG1 = HHI_BASE_ADDR+(0x44<<2);//0xff63c110;
-static  unsigned int RESET_LEVEL2 = 0xffd01088;
-static  unsigned int NN_clk = 0xff63c1c8;
-static  unsigned int NN_chipid = NN_CHIP_W400;
+static  uint32_t NN_clk = 0xff63c1c8;
+static  uint32_t nn_power_version = 0;
 
 
 static int hardwareResetNum = 0;
@@ -86,349 +90,403 @@ module_param(hardwareResetNum, int, 0644);
 static int nanoqFreq = 800000000;
 module_param(nanoqFreq, int, 0644);
 
-static void _InitDtsRegValue(IN gcsPLATFORM *Platform)
+gceSTATUS _InitDtsRegValue(IN gcsPLATFORM *Platform)
 {
-//     OUT gcsMODULE_PARAMETERS *Args;
+    int ret = 0;
+    struct resource *res = NULL;
     struct platform_device *pdev = Platform->device;
-       struct resource *res;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
-       if (res)
-       {
-               printk("reg resource 2, start: %ld,end: %ld\n",(unsigned long)res->start,(unsigned long)res->end);
-               HHI_NANOQ_MEM_PD_REG0 = (unsigned long)res->start;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
-       if (res)
-       {
-               printk("reg resource 3, start: %ld,end: %ld\n",(unsigned long)res->start,(unsigned long)res->end);
-               HHI_NANOQ_MEM_PD_REG1 = (unsigned long)res->start;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
-       if (res)
-       {
-               printk("reg resource 4, start: %ld,end: %ld\n",(unsigned long)res->start,(unsigned long)res->end);
-               RESET_LEVEL2 = (unsigned long)res->start;
-       }
-       if (HHI_NANOQ_MEM_PD_REG1 != 0xff63c110)
-       {
-               NN_chipid = NN_CHIP_SM1;
-       }
-
-       return;
+
+
+    res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+    if (res)
+    {
+        HHI_NANOQ_MEM_PD_REG0 = (unsigned long)res->start;
+        printk("reg resource 2, start: %lx,end: %lx\n",(unsigned long)res->start,(unsigned long)res->end);
+    }
+
+    res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+    if (res)
+    {
+        HHI_NANOQ_MEM_PD_REG1 = (unsigned long)res->start;
+        printk("reg resource 3, start: %lx,end: %lx\n",(unsigned long)res->start,(unsigned long)res->end);
+    }
+
+    res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
+    if (res)
+    {
+        RESET_LEVEL2 = (unsigned long)res->start;
+        printk("reg resource 4, start: %lx,end: %lx\n",(unsigned long)res->start,(unsigned long)res->end);
+    }
+
+    res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "NN_CLK");
+    if (res)
+    {
+        NN_clk = (unsigned long)res->start;
+        printk("reg resource NN_CLK, start: %lx,end: %lx\n",(unsigned long)res->start,(unsigned long)res->end);
+    }
+
+    ret = of_property_read_u32(pdev->dev.of_node,"nn_power_version",&nn_power_version);
+    printk("npu_version: %d\n",nn_power_version);
+    return gcvSTATUS_OK;
 }
 
 gceSTATUS _AdjustParam(IN gcsPLATFORM *Platform,OUT gcsMODULE_PARAMETERS *Args)
 {
+    struct resource *res = NULL;
     struct platform_device *pdev = Platform->device;
-       struct resource *res;
     int irqLine = platform_get_irq_byname(pdev, "galcore");
-       //dma_addr_t dma_start = 0;
-       //gceSTATUS ret;
-    printk("galcore irq number is %d.\n", irqLine);
+
+    if (irqLine >= 0)
+        printk("galcore irq number is %d.\n", irqLine);
     if (irqLine < 0) {
         printk("get galcore irq resource error\n");
         irqLine = platform_get_irq(pdev, 0);
         printk("galcore irq number is %d\n", irqLine);
+        if (irqLine < 0)
+            return gcvSTATUS_OUT_OF_RESOURCES;
     }
-    if (irqLine < 0) return gcvSTATUS_OUT_OF_RESOURCES;
     Args->irqs[gcvCORE_MAJOR] = irqLine;
+
     /*================read reg value from dts===============*/
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res) 
-       {
-               /*printk("reg resource 0,start:%ld,end:%ld",(unsigned long)res->start,(unsigned long)res->end);*/
-               Args->registerBases[0] = (gctPHYS_ADDR_T)res->start;
-               Args->registerSizes[0] = (gctSIZE_T)(res->end - res->start+1);
-               /*printk("read from dts,regbase:0x%llx,size:0x%lx\n",Args->registerBases[0],Args->registerSizes[0]);*/
-       } 
-       else 
-       {
-               printk("no memory resource 0\n");
-               Args->registerBases[0] = 0xFF100000;
-               Args->registerSizes[0] = 2 << 10;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (res)
-       {
-               /*printk("reg resource 1,start:%ld,end:%ld",(unsigned long)res->start,(unsigned long)res->end);*/
-               Args->sRAMBases[0][0] = ~0L;
-               if (NN_chipid == NN_CHIP_W400)
-               {
-                       Args->sRAMBases[0][1] = (gctPHYS_ADDR_T)res->start;
-               }
-               else
-               {
-                       Args->sRAMBases[0][1] = ~0L;
-               }
-               Args->sRAMBases[0][2] = ~0L;
-               Args->contiguousBase = 0;
-               Args->contiguousSize = (gctSIZE_T)(res->end - res->start+1);
-               /*printk("read from dts,srambase:0x%llx,contiguousize:0x%lx\n",Args->sRAMBases[0][1],Args->contiguousSize);
-               if(Args->contiguousSize > 0)
-               {
-                       ret = _DmaAlloc(pdev,Args->contiguousSize,&dma_start);
-                       if(ret == gcvSTATUS_OK)
-                       {
-                               Args->contiguousBase = (gctPHYS_ADDR_T)dma_start;
-                               printk("contiguousBase use from cma,page size is %ld\n",Args->contiguousSize/PAGE_SIZE);
-                       }
-               }*/
-       }
-       else
-       {
-               printk("no memory resource 1\n");
-               Args->contiguousBase = 0;
-               Args->contiguousSize = 0x400000;
-               Args->sRAMBases[0][0] = ~0L;
-               Args->sRAMBases[0][1] = ~0L;
-               Args->sRAMBases[0][2] = ~0L;
-       }
-       Args->registerSizes[0] = 0x800;
+    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+    if (res)
+    {
+        Args->registerBases[0] = (gctPHYS_ADDR_T)res->start;
+        Args->registerSizes[0] = (gctSIZE_T)(res->end - res->start+1);
+    }
+    else
+    {
+        printk("no memory resource 0\n");
+        Args->registerBases[0] = 0xFF100000;
+        Args->registerSizes[0] = 2 << 10;
+    }
+
+    res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+    if (res)
+    {
+        Args->extSRAMBases[0] = (gctPHYS_ADDR_T)res->start;
+
+        Args->contiguousBase = 0;
+        Args->contiguousSize = (gctSIZE_T)(res->end - res->start+1);
+    }
+    else
+    {
+        printk("no memory resource 1\n");
+        Args->contiguousBase = 0;
+        Args->contiguousSize = 0x400000;
+    }
     return gcvSTATUS_OK;
 }
 
-int _RegWrite(unsigned int reg, unsigned int writeval)
+gceSTATUS _RegWrite(uint32_t reg, uint32_t writeval)
 {
-       void __iomem *vaddr;
-       reg = round_down(reg, 0x3);
-
-       vaddr = ioremap(reg, 0x4);
-       writel(writeval, vaddr);
-       iounmap(vaddr);
-       
-       return 0;
+    void __iomem *vaddr = NULL;
+    reg = round_down(reg, 0x3);
+
+    vaddr = ioremap(reg, 0x4);
+    writel(writeval, vaddr);
+    iounmap(vaddr);
+
+    return gcvSTATUS_OK;
 }
 
-int _RegRead(unsigned int reg,unsigned int *readval)
+gceSTATUS _RegRead(uint32_t reg,uint32_t *readval)
 {
-       void __iomem *vaddr;
-       reg = round_down(reg, 0x3);
-       vaddr = ioremap(reg, 0x4);
-       *readval = readl(vaddr);
-       iounmap(vaddr);
-       return 0;
+    void __iomem *vaddr = NULL;
+    reg = round_down(reg, 0x3);
+    vaddr = ioremap(reg, 0x4);
+    *readval = readl(vaddr);
+    iounmap(vaddr);
+    return gcvSTATUS_OK;
 }
-
-int get_nna_status(struct platform_device *dev)
+gceSTATUS get_nna_status(struct platform_device *dev)
 {
-       unsigned int readReg=0;
-       struct platform_device *pdev = dev;
-       u32  nn_ef[2];
-       int ret;
-
-       ret = of_property_read_u32_array(pdev->dev.of_node,"nn_efuse", &nn_ef[0], 2);
-       if (ret == 0)
-       {
-               _RegRead(nn_ef[0],&readReg);
-               readReg = (readReg & nn_ef[1]);
-               if (readReg == 0)
-                       return 0;
-               else
-                       return 1;
-       }
-       else
-       {
-               return 0;
-       }
+    int ret = 0;
+    uint32_t readReg = 0;
+    uint32_t nn_ef[2];
+    struct platform_device *pdev = dev;
+
+    ret = of_property_read_u32_array(pdev->dev.of_node,"nn_efuse", &nn_ef[0], 2);
+    if (ret == 0)
+    {
+        _RegRead(nn_ef[0],&readReg);
+        readReg = (readReg & nn_ef[1]);
+        if (readReg == 0)
+            return gcvSTATUS_OK;
+        else
+            return gcvSTATUS_MISMATCH;
+    }
+    else
+    {
+        return gcvSTATUS_OK;
+    }
 }
 //us
-void delay(unsigned int time)
+void delay(uint32_t time)
 {
-       int i,j;
-       for(j=0;j<1000;j++)
-       {
-               for(i = 0;i<time;i++);
-       }
+    int i = 0,j = 0;
+    for (j=0;j<1000;j++)
+    {
+        for (i = 0;i<time;i++);
+    }
 }
-/*
+/********To Do: add dynamic set clock function*********/
+#if 0
 static void set_clock(struct platform_device *pdev)
 {
-       struct clk *npu_axi_clk = NULL;
-       struct clk *npu_core_clk = NULL;
-       npu_axi_clk = clk_get(&pdev->dev, "cts_vipnanoq_axi_clk_composite");
-       if (IS_ERR(npu_axi_clk))
-       {
-               printk("%s: get npu_axi_clk error!!!\n", __func__);
-               return;
-       }
-       else
-       {
-               clk_prepare_enable(npu_axi_clk);
-       }
-       clk_set_rate(npu_axi_clk, nanoqFreq);
-       
-       npu_core_clk = clk_get(&pdev->dev, "cts_vipnanoq_core_clk_composite");
-       if (IS_ERR(npu_core_clk))
-       {
-               printk("%s: get npu_core_clk error!!!\n", __func__);
-               return;
-       }
-       else
-       {
-               clk_prepare_enable(npu_core_clk);
-       }
-       clk_set_rate(npu_core_clk, nanoqFreq);
-       return;
-}*/
+    struct clk *npu_axi_clk = NULL;
+    struct clk *npu_core_clk = NULL;
+    npu_axi_clk = clk_get(&pdev->dev, "cts_vipnanoq_axi_clk_composite");
+    if (IS_ERR(npu_axi_clk))
+   {
+        printk("%s: get npu_axi_clk error!!!\n", __func__);
+        return;
+    }
+    else
+    {
+        clk_prepare_enable(npu_axi_clk);
+    }
+    clk_set_rate(npu_axi_clk, nanoqFreq);
+
+    npu_core_clk = clk_get(&pdev->dev, "cts_vipnanoq_core_clk_composite");
+    if (IS_ERR(npu_core_clk))
+    {
+        printk("%s: get npu_core_clk error!!!\n", __func__);
+        return;
+    }
+    else
+    {
+        clk_prepare_enable(npu_core_clk);
+    }
+    clk_set_rate(npu_core_clk, nanoqFreq);
+    return;
+}
+#endif
+
+void Getpower_88(void)
+{
+    uint32_t readReg = 0;
+    _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
+    readReg = (readReg & 0xfffcffff);
+    _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
+
+    _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0x0);
+    _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0x0);
+
+    _RegRead(RESET_LEVEL2,&readReg);
+    readReg = (readReg & 0xffffefff);
+    _RegWrite(RESET_LEVEL2, readReg);
+
+    _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
+    readReg = (readReg & 0xfffcffff);
+    _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
+
+    _RegRead(RESET_LEVEL2,&readReg);
+    readReg = (readReg | (0x1<<12));
+    _RegWrite(RESET_LEVEL2, readReg);
+
+    _RegWrite(NN_clk, 0x7000700);
+}
+
+void Getpower_99(void)
+{
+    uint32_t readReg = 0;
+    _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
+    readReg = (readReg & 0xfffeffff);
+    _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
+
+    _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0x0);
+    _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0x0);
+
+    _RegRead(RESET_LEVEL2,&readReg);
+    readReg = (readReg & 0xffffefff);
+    _RegWrite(RESET_LEVEL2, readReg);
+
+    _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
+    readReg = (readReg & 0xfffeffff);
+    _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
+
+    _RegRead(RESET_LEVEL2,&readReg);
+    readReg = (readReg | (0x1<<12));
+    _RegWrite(RESET_LEVEL2, readReg);
+
+    _RegWrite(NN_clk, 0x7000700);
+}
+void Getpower_a1(void)
+{
+    uint32_t readReg = 0;
+    _RegRead(RESET_LEVEL2,&readReg);
+    readReg = (readReg & (~(1<<3)));
+    _RegWrite(RESET_LEVEL2, readReg);
+
+    _RegRead(P_PWRCTRL_PWR_OFF1,&readReg);
+    readReg = (readReg & (~(1<<3)));
+    _RegWrite(P_PWRCTRL_PWR_OFF1, readReg);
+
+    _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0x0);
+    _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0x0);
+
+    _RegRead(P_PWRCTRL_ISO_EN1,&readReg);
+    readReg = (readReg & (~(1<<3)));
+    _RegWrite(P_PWRCTRL_ISO_EN1, readReg);
+
+    _RegRead(RESET_LEVEL2,&readReg);
+    readReg = (readReg | (1<<3));
+    _RegWrite(RESET_LEVEL2, readReg);
+
+    _RegWrite(NN_clk, 0x3000300);
+}
 gceSTATUS _GetPower(IN gcsPLATFORM *Platform)
 {
-       unsigned int readReg=0;
-       _InitDtsRegValue(Platform);
-#if 0
-       unsigned int readReg=0;
-       _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
-       readReg = (readReg & 0xfffcffff);
-       _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
-       _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
-       readReg = (readReg & 0xfffcffff);
-       _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0x0);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0x0);
-//     set_clock(Platform->device);
-       _RegWrite(NN_clk, 0x7000700);
-       delay(500);
-#else
-       _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
-       readReg = (readReg & 0xfffcffff);
-       _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0x0);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0x0);
-       _RegRead(RESET_LEVEL2,&readReg);
-       readReg = (readReg & 0xffffefff);
-       _RegWrite(RESET_LEVEL2, readReg);
-       _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
-       readReg = (readReg & 0xfffcffff);
-       _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
-       _RegRead(RESET_LEVEL2,&readReg);
-       readReg = (readReg | (0x1<<12));
-       _RegWrite(RESET_LEVEL2, readReg);
-//     set_clock(Platform->device);
-       _RegWrite(NN_clk, 0x7000700);
-       //mdelay(1);
-#endif
+    _InitDtsRegValue(Platform);
+    switch (nn_power_version)
+    {
+        case 1:
+            Getpower_a1();
+            break;
+        case 2:
+            Getpower_88();
+            break;
+        case 3:
+            Getpower_99();
+            break;
+        default:
+            printk("not find power_version\n");
+    }
     return gcvSTATUS_OK;
 }
 
+void Downpower_88(void)
+{
+    uint32_t readReg = 0;
+    _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
+    readReg = (readReg | 0x30000);
+    _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
+
+    _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0xffffffff);
+    _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0xffffffff);
+
+    _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
+    readReg = (readReg | 0x30000);
+    _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
+}
+void Downpower_99(void)
+{
+    _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0xffffffff);
+    _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0xffffffff);
+}
+void Downpower_a1(void)
+{
+    uint32_t readReg=0;
+    _RegRead(P_PWRCTRL_ISO_EN1,&readReg);
+    readReg = (readReg | (1<<3));
+    _RegWrite(P_PWRCTRL_ISO_EN1, readReg);
+
+    _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0xffffffff);
+    _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0xffffffff);
+
+    _RegRead(P_PWRCTRL_PWR_OFF1,&readReg);
+    readReg = (readReg | (1<<3));
+    _RegWrite(P_PWRCTRL_PWR_OFF1, readReg);
+}
 gceSTATUS _DownPower(IN gcsPLATFORM *Platform)
 {
-       unsigned int readReg=0;
-       printk("====>>>>downpower for putpower\n");
-       if (NN_chipid == NN_CHIP_W400)
-       {
-               _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
-               readReg = (readReg | 0x30000);
-               _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
-       }
-       _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0xffffffff);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0xffffffff);
-       if (NN_chipid == NN_CHIP_W400)
-       {
-               _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
-               readReg = (readReg | 0x30000);
-               _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
-       }
+    switch (nn_power_version)
+    {
+        case 1:
+            Downpower_a1();
+            break;
+        case 2:
+            Downpower_88();
+            break;
+        case 3:
+            Downpower_99();
+            break;
+        default:
+            printk("not find power_version\n");
+    }
     return gcvSTATUS_OK;
 }
 
 gceSTATUS _Reset(IN gcsPLATFORM * Platform, IN gceCORE GPU)
 {
-       unsigned int readReg=0;
-
-       printk("====>>>>begin npu hardware reset!\n");
-       _RegWrite(RESET_LEVEL2, 0xffffefff);
-       /*==========power off=============*/
-       _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0xffffffff);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0xffffffff);
-       if (NN_chipid == NN_CHIP_W400)
-       {
-               _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
-               readReg = (readReg | 0x30000);
-               _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
-
-               _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
-               readReg = (readReg | 0x30000);
-               _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
-       }
-       mdelay(10);
-       /*==========power on===============*/
-       _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
-       readReg = (readReg & 0xfffcffff);
-       _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
-       _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
-       readReg = (readReg & 0xfffcffff);
-       _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0x0);
-       _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0x0);
-//     set_clock(Platform->device);
-       _RegWrite(NN_clk, 0x7000700);
-       mdelay(1);
-       _RegWrite(RESET_LEVEL2, 0xffffffff);
-       mdelay(2);
-       printk("====>>>>npu hardware reset end!\n");
-       hardwareResetNum++;
-       if (hardwareResetNum > 10000)
-       {
-               printk("hardwareResetNum is too large over 10000,just set zero\n");
-               hardwareResetNum = 0;
-       }
-
-    return gcvSTATUS_OK;   //gcvSTATUS_NOT_SUPPORTED;
+    switch (nn_power_version)
+    {
+        case 1:
+            Downpower_a1();
+            mdelay(10);
+            Getpower_a1();
+            break;
+        case 2:
+            Downpower_88();
+            mdelay(10);
+            Getpower_88();
+            break;
+        case 3:
+            Downpower_99();
+            mdelay(10);
+            Getpower_99();
+            break;
+        default:
+            printk("not find power_version\n");
+    }
+    mdelay(2);
+    printk("====>>>>npu hardware reset end!\n");
+    hardwareResetNum++;
+    if (hardwareResetNum > 10000)
+    {
+        printk("hardwareResetNum is too large over 10000,just set zero\n");
+        hardwareResetNum = 0;
+    }
+    return gcvSTATUS_OK;
 }
+
+
 gceSTATUS  _SetPower(IN gcsPLATFORM * Platform,IN gceCORE GPU,IN gctBOOL Enable)
 {
-       unsigned int readReg=0;
-       printk("_setpower,control status:%d\n",Enable);
-       if(Enable == 0)
-       {
-               printk("====>>>>poweroff in _SetPower\n");
-               if (NN_chipid == NN_CHIP_W400)
-               {
-                       _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
-                       readReg = (readReg | 0x30000);
-                       _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
-               }
-               _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0xffffffff);
-               _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0xffffffff);
-               if (NN_chipid == NN_CHIP_W400)
-               {
-                       _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
-                       readReg = (readReg | 0x30000);
-                       _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
-               }
-       }
-       else
-       {
-               printk("====>>>>poweron in _SetPower\n");
-               _RegRead(AO_RTI_GEN_PWR_SLEEP0,&readReg);
-               readReg = (readReg & 0xfffcffff);
-               _RegWrite(AO_RTI_GEN_PWR_SLEEP0, readReg);
-               _RegWrite(HHI_NANOQ_MEM_PD_REG0, 0x0);
-               _RegWrite(HHI_NANOQ_MEM_PD_REG1, 0x0);
-               _RegRead(RESET_LEVEL2,&readReg);
-               readReg = (readReg & 0xffffefff);
-               _RegWrite(RESET_LEVEL2, readReg);
-               _RegRead(AO_RTI_GEN_PWR_ISO0,&readReg);
-               readReg = (readReg & 0xfffcffff);
-               _RegWrite(AO_RTI_GEN_PWR_ISO0, readReg);
-               _RegRead(RESET_LEVEL2,&readReg);
-               readReg = (readReg | (0x1<<12));
-               _RegWrite(RESET_LEVEL2, readReg);
-//             set_clock(Platform->device);
-               _RegWrite(NN_clk, 0x7000700);
-       }
-       return gcvSTATUS_OK;
+    if (Enable == 0)
+    {
+        switch (nn_power_version)
+        {
+            case 1:
+                Downpower_a1();
+                break;
+            case 2:
+                Downpower_88();
+                break;
+            case 3:
+                Downpower_99();
+                break;
+            default:
+                printk("not find power_version\n");
+        }
+    }
+    else
+    {
+        switch (nn_power_version)
+        {
+            case 1:
+                Getpower_a1();
+                break;
+            case 2:
+                Getpower_88();
+                break;
+            case 3:
+                Getpower_99();
+                break;
+            default:
+                printk("not find power_version\n");
+        }
+    }
+    return gcvSTATUS_OK;
 }
 static gcsPLATFORM_OPERATIONS default_ops =
 {
     .adjustParam   = _AdjustParam,
-       .getPower  = _GetPower,
-       .reset = _Reset,
-       .putPower = _DownPower,
-       .setPower = _SetPower,
+    .getPower  = _GetPower,
+    .reset = _Reset,
+    .putPower = _DownPower,
+    .setPower = _SetPower,
 };
 
 static gcsPLATFORM default_platform =
@@ -452,7 +510,7 @@ int gckPLATFORM_Init(struct platform_driver *pdrv, gcsPLATFORM **platform)
     pdrv->driver.of_match_table = galcore_dev_match;
 
     *platform = &default_platform;
-       /*  default_dev = platform;  hot plug just not support  */
+    /*  default_dev = platform;  hot plug just not support  */
     return 0;
 }
 
index cef4f6f4074006dbad456c204e5322706627915c..a01a43fcd2112c3d7553a989c98fb9561e299c54 100755 (executable)
@@ -1,3 +1,4 @@
 ifeq ($(USE_LINUX_PCIE), 1)
 EXTRA_CFLAGS +=-DgcdIRQ_SHARED
 endif
+EXTRA_CFLAGS += -DNO_DMA_COHERENT=1
index 7c9897a029bfc5c41ad1b688b66d71b05dd3dc20..7c915df698e2365fde566e622aee9e7f1d78fff3 100644 (file)
@@ -69,9 +69,17 @@ _AdjustParam(
     OUT gcsMODULE_PARAMETERS *Args
     );
 
+gceSTATUS
+_GetGPUPhysical(
+    IN gcsPLATFORM * Platform,
+    IN gctPHYS_ADDR_T CPUPhysical,
+    OUT gctPHYS_ADDR_T *GPUPhysical
+    );
+
 static struct _gcsPLATFORM_OPERATIONS default_ops =
 {
     .adjustParam   = _AdjustParam,
+    .getGPUPhysical = _GetGPUPhysical,
 };
 
 #if USE_LINUX_PCIE
@@ -79,16 +87,29 @@ static struct _gcsPLATFORM_OPERATIONS default_ops =
 #define MAX_PCIE_DEVICE 4
 #define MAX_PCIE_BAR    6
 
+typedef struct _gcsBARINFO
+{
+    gctPHYS_ADDR_T base;
+    gctSIZE_T size;
+    gctPOINTER logical;
+}
+gcsBARINFO, *gckBARINFO;
+
 struct _gcsPCIEInfo
 {
-    gctPOINTER bar[MAX_PCIE_BAR];
+    gcsBARINFO bar[MAX_PCIE_BAR];
     struct pci_dev *pdev;
+    gctPHYS_ADDR_T sram_bases[gcvSRAM_EXT_COUNT];
+    gctPHYS_ADDR_T sram_gpu_bases[gcvSRAM_EXT_COUNT];
+    uint32_t sram_sizes[gcvSRAM_EXT_COUNT];
+    int sram_bars[gcvSRAM_EXT_COUNT];
+    int sram_offsets[gcvSRAM_EXT_COUNT];
 };
 
 struct _gcsPLATFORM_PCIE
 {
     struct _gcsPLATFORM base;
-    struct _gcsPCIEInfo pcieInfo[MAX_PCIE_DEVICE];
+    struct _gcsPCIEInfo pcie_info[MAX_PCIE_DEVICE];
     unsigned int device_number;
 };
 
@@ -102,6 +123,50 @@ struct _gcsPLATFORM_PCIE default_platform =
     },
 };
 
+void
+_QueryBarInfo(
+    struct pci_dev *Pdev,
+    gctPHYS_ADDR_T *BarAddr,
+    gctSIZE_T *BarSize,
+    gctUINT BarNum
+    )
+{
+    gctUINT addr;
+    gctUINT size;
+
+    /* Read the bar address */
+    if (pci_read_config_dword(Pdev, PCI_BASE_ADDRESS_0 + BarNum * 0x4, &addr) < 0)
+    {
+        return;
+    }
+
+    /* Read the bar size */
+    if (pci_write_config_dword(Pdev, PCI_BASE_ADDRESS_0 + BarNum * 0x4, 0xffffffff) < 0)
+    {
+        return;
+    }
+
+    if (pci_read_config_dword(Pdev, PCI_BASE_ADDRESS_0 + BarNum * 0x4, &size) < 0)
+    {
+        return;
+    }
+
+    size &= 0xfffffff0;
+    size  = ~size;
+    size += 1;
+
+    /* Write back the bar address */
+    if (pci_write_config_dword(Pdev, PCI_BASE_ADDRESS_0 + BarNum * 0x4, addr) < 0)
+    {
+        return;
+    }
+
+    gcmkPRINT("Bar%d addr=0x%x size=0x%x", BarNum, addr, size);
+
+    *BarAddr = addr;
+    *BarSize = size;
+}
+
 #else
 
 static struct _gcsPLATFORM default_platform =
@@ -119,10 +184,12 @@ _AdjustParam(
 {
 #if USE_LINUX_PCIE
     struct _gcsPLATFORM_PCIE *pcie_platform = (struct _gcsPLATFORM_PCIE *)Platform;
-    struct pci_dev *pdev = pcie_platform->pcieInfo[0].pdev;
-    unsigned char   irqline = pdev->irq;
+    struct pci_dev *pdev = pcie_platform->pcie_info[0].pdev;
+    unsigned char irqline = pdev->irq;
     unsigned int i;
-    unsigned int devIndex, coreIndex = 0;
+
+    unsigned int dev_index, core_index = 0;
+    int sram_bar, sram_offset;
 
     if (Args->irqs[gcvCORE_2D] != -1)
     {
@@ -132,26 +199,122 @@ _AdjustParam(
     {
         Args->irqs[gcvCORE_MAJOR] = irqline;
     }
-    for (devIndex = 0; devIndex < pcie_platform->device_number; devIndex++)
+
+    for (dev_index = 0; dev_index < pcie_platform->device_number; dev_index++)
     {
-        struct pci_dev * pcieDev = pcie_platform->pcieInfo[devIndex].pdev;
+        struct pci_dev * pcieDev = pcie_platform->pcie_info[dev_index].pdev;
+
+        for (i = 0; i < MAX_PCIE_BAR; i++)
+        {
+            _QueryBarInfo(
+                pcieDev,
+                &pcie_platform->pcie_info[dev_index].bar[i].base,
+                &pcie_platform->pcie_info[dev_index].bar[i].size,
+                i
+                );
+        }
+
         for (i = 0; i < gcvCORE_COUNT; i++)
         {
             if (Args->bars[i] != -1)
             {
-                Args->irqs[coreIndex] = pcieDev->irq;
-                Args->registerBasesMapped[coreIndex]    =
-                pcie_platform->pcieInfo[devIndex].bar[i] =
-                    (gctPOINTER)pci_iomap(pcieDev, Args->bars[i], Args->registerSizes[coreIndex]);
-                coreIndex++;
+                Args->irqs[core_index] = pcieDev->irq;
+
+                /* VIV bitfile: Merge last 4 cores to last one bar to support 8 cores. */
+                if (Args->bars[i] == 5)
+                {
+                    Args->registerBasesMapped[4] =
+                    pcie_platform->pcie_info[dev_index].bar[i].logical =
+                        (gctPOINTER)pci_iomap(pcieDev, Args->bars[i], 0x500000);
+                    Args->registerBasesMapped[5] = Args->registerBasesMapped[4] + 0x100000;
+                    Args->registerBasesMapped[6] = Args->registerBasesMapped[5] + 0x100000;
+                    Args->registerBasesMapped[7] = Args->registerBasesMapped[6] + 0x100000;
+
+                    Args->irqs[5] =
+                    Args->irqs[6] =
+                    Args->irqs[7] = Args->irqs[4];
+
+                    continue;
+                }
+
+                if (Args->regOffsets[i])
+                {
+                    gcmkASSERT(Args->regOffsets[i] + Args->registerSizes[core_index]
+                               < pcie_platform->pcie_info[dev_index].bar[Args->bars[i]].size);
+                }
+
+                Args->registerBasesMapped[core_index] =
+                pcie_platform->pcie_info[dev_index].bar[i].logical =
+                    (gctPOINTER)pci_iomap(pcieDev, Args->bars[i], Args->registerSizes[core_index] + Args->regOffsets[i]) + Args->regOffsets[i];
+
+                core_index++;
+            }
+        }
+
+        for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
+        {
+            pcie_platform->pcie_info[dev_index].sram_bases[i] =
+            pcie_platform->pcie_info[dev_index].sram_gpu_bases[i] = Args->extSRAMBases[i];
+
+            pcie_platform->pcie_info[dev_index].sram_sizes[i] = Args->extSRAMSizes[i];
+
+            pcie_platform->pcie_info[dev_index].sram_bars[i] = sram_bar = Args->sRAMBars[i];
+            pcie_platform->pcie_info[dev_index].sram_offsets[i] = sram_offset = Args->sRAMOffsets[i];
+
+            /* Get CPU view SRAM base address from bar address and bar inside offset. */
+            if (sram_bar != -1 && sram_offset != -1)
+            {
+                pcie_platform->pcie_info[dev_index].sram_bases[i] = Args->extSRAMBases[i]
+                                                                  = pcie_platform->pcie_info[dev_index].bar[sram_bar].base
+                                                                  + sram_offset;
             }
         }
     }
+
     Args->contiguousRequested = gcvTRUE;
 #endif
     return gcvSTATUS_OK;
 }
 
+gceSTATUS
+_GetGPUPhysical(
+    IN gcsPLATFORM * Platform,
+    IN gctPHYS_ADDR_T CPUPhysical,
+    OUT gctPHYS_ADDR_T *GPUPhysical
+    )
+{
+#if USE_LINUX_PCIE
+    struct _gcsPLATFORM_PCIE *pcie_platform = (struct _gcsPLATFORM_PCIE *)Platform;
+    /* Only support 1 external shared SRAM currently. */
+    gctPHYS_ADDR_T sram_base = pcie_platform->pcie_info[0].sram_bases[0];
+    gctPHYS_ADDR_T sram_gpu_base = pcie_platform->pcie_info[0].sram_gpu_bases[0];
+    uint32_t sram_size = pcie_platform->pcie_info[0].sram_sizes[0];
+
+    /* TODO: We should always set axi sram size by insmod parameters, never from feature database. */
+    if (!sram_size && Platform->dev && Platform->dev->extSRAMSizes[0])
+    {
+        sram_size = Platform->dev->extSRAMSizes[0];
+    }
+
+    if (sram_base != gcvINVALID_PHYSICAL_ADDRESS && sram_gpu_base != gcvINVALID_PHYSICAL_ADDRESS && sram_size)
+    {
+        if ((CPUPhysical >= sram_base) && (CPUPhysical < (sram_base + sram_size)))
+        {
+            *GPUPhysical = CPUPhysical - sram_base + sram_gpu_base;
+        }
+        else
+        {
+            *GPUPhysical = CPUPhysical;
+        }
+    }
+    else
+#endif
+    {
+        *GPUPhysical = CPUPhysical;
+    }
+
+    return gcvSTATUS_OK;
+}
 
 #if USE_LINUX_PCIE
 static const struct pci_device_id vivpci_ids[] = {
@@ -197,7 +360,7 @@ static int gpu_sub_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         printk(KERN_ERR "galcore: Failed to enable MSI.\n");
     }
 #endif
-    default_platform.pcieInfo[default_platform.device_number++].pdev = pdev;
+    default_platform.pcie_info[default_platform.device_number++].pdev = pdev;
     return 0;
 }
 
@@ -265,16 +428,16 @@ int gckPLATFORM_Terminate(struct _gcsPLATFORM *platform)
 
 #if USE_LINUX_PCIE
     {
-        unsigned int devIndex;
+        unsigned int dev_index;
         struct _gcsPLATFORM_PCIE *pcie_platform = (struct _gcsPLATFORM_PCIE *)platform;
-        for (devIndex = 0; devIndex < pcie_platform->device_number; devIndex++)
+        for (dev_index = 0; dev_index < pcie_platform->device_number; dev_index++)
         {
             unsigned int i;
             for (i = 0; i < MAX_PCIE_BAR; i++)
             {
-                if (pcie_platform->pcieInfo[devIndex].bar[i] != 0)
+                if (pcie_platform->pcie_info[dev_index].bar[i].logical != 0)
                 {
-                    pci_iounmap(pcie_platform->pcieInfo[devIndex].pdev, pcie_platform->pcieInfo[devIndex]. bar[i]);
+                    pci_iounmap(pcie_platform->pcie_info[dev_index].pdev, pcie_platform->pcie_info[dev_index].bar[i].logical);
                 }
             }
         }
index b52a77dd91865262ab493285ef14cec8125e9cd1..f75e93fecbed1747724fdccdc19d685a54397652 100644 (file)
@@ -48,7 +48,15 @@ LOCAL_C_INCLUDES += \
        system/core/libsync/include
 endif
 
+ifeq ($(shell expr $(PLATFORM_SDK_VERSION) ">=" 28),1)
+LOCAL_C_INCLUDES += \
+   system/core/include
+endif
+
 LOCAL_MODULE         := libhalosuser
 LOCAL_MODULE_TAGS    := optional
+ifeq ($(PLATFORM_VENDOR),1)
+LOCAL_VENDOR_MODULE  := true
+endif
 include $(BUILD_STATIC_LIBRARY)
 
index 2abb9e7eda8d24e937ebd1fb0bd47e702ed4438e..2a2df99ab37d4a8c9e4bec601e05abfe1f36ff50 100644 (file)
@@ -1,12 +1,12 @@
 bin_r/gc_hal_user_debug.o: gc_hal_user_debug.c gc_hal_user_linux.h \
  /home/nick/code/fenix/nanoq/hal/user/gc_hal_user.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal.h \
- /home/nick/code/fenix/nanoq/hal/inc/gc_hal_rename.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_types.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_version.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_options.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_enum.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_base.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_hal_debug_zones.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_profiler.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_driver.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_statistics.h \
@@ -21,13 +21,13 @@ bin_r/gc_hal_user_debug.o: gc_hal_user_debug.c gc_hal_user_linux.h \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_os_atomic.h \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_debug.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_engine.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/gc_vsc_precomp.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_gcsl.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_lib_link.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_priv_mapping.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_program_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_kernel_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_vsc_precomp.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_gcsl.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_lib_link.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_priv_mapping.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_program_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_kernel_profile.h \
  /home/nick/code/fenix/nanoq/hal/user/gc_hal_user_shader.h
index 8f3c40a69b2d84a9caa070fe6311862434412b98..bbb9772f432ccc92e691cef1630605cf01ba7fca 100644 (file)
@@ -4,10 +4,10 @@ bin_r/gc_hal_user_math.o: gc_hal_user_math.c \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_options.h gc_hal_user_math.h \
  gc_hal_user_linux.h /home/nick/code/fenix/nanoq/hal/user/gc_hal_user.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal.h \
- /home/nick/code/fenix/nanoq/hal/inc/gc_hal_rename.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_types.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_enum.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_base.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_hal_debug_zones.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_profiler.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_driver.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_statistics.h \
@@ -22,13 +22,13 @@ bin_r/gc_hal_user_math.o: gc_hal_user_math.c \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_os_atomic.h \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_debug.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_engine.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/gc_vsc_precomp.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_gcsl.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_lib_link.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_priv_mapping.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_program_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_kernel_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_vsc_precomp.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_gcsl.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_lib_link.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_priv_mapping.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_program_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_kernel_profile.h \
  /home/nick/code/fenix/nanoq/hal/user/gc_hal_user_shader.h
index 305cd7008e35be2dd5d87847f90adab3df5d809d..1506ffeacb03258d1a4fb5b6316c93b9609ade05 100644 (file)
@@ -1,12 +1,12 @@
 bin_r/gc_hal_user_os.o: gc_hal_user_os.c gc_hal_user_linux.h \
  /home/nick/code/fenix/nanoq/hal/user/gc_hal_user.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal.h \
- /home/nick/code/fenix/nanoq/hal/inc/gc_hal_rename.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_types.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_version.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_options.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_enum.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_base.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_hal_debug_zones.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_profiler.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_driver.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_statistics.h \
@@ -21,14 +21,14 @@ bin_r/gc_hal_user_os.o: gc_hal_user_os.c gc_hal_user_linux.h \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_os_atomic.h \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_debug.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_engine.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/gc_vsc_precomp.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_gcsl.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_lib_link.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_priv_mapping.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_program_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_kernel_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_vsc_precomp.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_gcsl.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_lib_link.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_priv_mapping.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_program_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_kernel_profile.h \
  /home/nick/code/fenix/nanoq/hal/user/gc_hal_user_shader.h \
  gc_hal_user_os_atomic.h gc_hal_user_platform.h
index 9da0e0beb0eacd11277381356ddd7924a7040848..f0d8afbacae0e4da67532a81fdba3f3c1856d0ea 100644 (file)
@@ -3,12 +3,12 @@ bin_r/gc_hal_user_platform_default.o: \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_linux.h \
  /home/nick/code/fenix/nanoq/hal/user/gc_hal_user.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal.h \
- /home/nick/code/fenix/nanoq/hal/inc/gc_hal_rename.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_types.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_version.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_options.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_enum.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_base.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_hal_debug_zones.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_profiler.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_driver.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_statistics.h \
@@ -23,14 +23,14 @@ bin_r/gc_hal_user_platform_default.o: \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_os_atomic.h \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_debug.h \
  /home/nick/code/fenix/nanoq/hal/inc/gc_hal_engine.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/gc_vsc_precomp.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_drvi_interface.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/old_impl/gc_vsc_old_gcsl.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_lib_link.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_priv_mapping.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_shader_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_program_profile.h \
- /home/nick/code/fenix/nanoq/compiler/libVSC/include/drvi/gc_vsc_drvi_kernel_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/gc_vsc_precomp.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_drvi_interface.h \
+ /home/nick/code/fenix/nanoq/hal/inc/old_impl/gc_vsc_old_gcsl.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_lib_link.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_priv_mapping.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_shader_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_program_profile.h \
+ /home/nick/code/fenix/nanoq/hal/inc/drvi/gc_vsc_drvi_kernel_profile.h \
  /home/nick/code/fenix/nanoq/hal/user/gc_hal_user_shader.h \
  /home/nick/code/fenix/nanoq/hal/os/linux/user/gc_hal_user_platform.h
index 9db0052a705a7762e91134ed77d3a885f342115e..afdb34fba62af63c353f79fd344232b8c5c7b14b 100644 (file)
 
 static gceSTATUS _lastError  = gcvSTATUS_OK;
 static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
-static gctUINT32 _debugZones[16] =
-{
-    /*Others*/  gcvZONE_NONE,
-    /* HAL  */  gcvZONE_NONE,
-    /* EGL value scope 0x3FF*/          gcvZONE_NONE,
-    /* ES11 value scope 0x3FFFFF */     gcvZONE_NONE,
-    /* ES2/3 */ gcvZONE_NONE,
-    /* VG11 value scope 0xfFF*/         gcvZONE_NONE,
-    /* GL   */  gcvZONE_NONE,
-    /* DFB  */  gcvZONE_NONE,
-    /* GDI  */  gcvZONE_NONE,
-    /* D3D  */  gcvZONE_NONE,
-    /* CL   */  gcvZONE_NONE,
-    /* VX   */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE
-};
 
-static gctBOOL _dumpAPIZones[16] =
+#define gcdZONE_ARRAY_SIZE  16
+
+static gctUINT32 _debugZones[gcdZONE_ARRAY_SIZE] =
 {
-    /*Others*/  gcvFALSE,
-    /* HAL  */  gcvFALSE,
-    /* EGL  */  gcvFALSE,
-    /* ES11 */  gcvFALSE,
-    /* ES20 */  gcvFALSE,
-    /* VG11 */  gcvFALSE,
-    /* GL   */  gcvFALSE,
-    /* DFB  */  gcvFALSE,
-    /* GDI  */  gcvFALSE,
-    /* D3D  */  gcvFALSE,
-    /* CL   */  gcvFALSE,
-    /* VX   */  gcvFALSE,
-    /* ---- */  gcvFALSE,
-    /* ---- */  gcvFALSE,
-    /* ---- */  gcvFALSE,
-    /* ---- */  gcvFALSE
+    /* Subzones of HAL User */        gcdZONE_NONE,
+    /* Subzones of EGL API  */        gcdZONE_NONE,
+    /* Subzones of ES11 API */        gcdZONE_NONE,
+    /* Subzones of ES30 API */        gcdZONE_NONE,
+    /* Subzones of GL40 API */        gcdZONE_NONE,
+    /* Subzones of VG3D API */        gcdZONE_NONE,
+    /* Subzones of CL API   */        gcdZONE_NONE,
+    /* Subzones of VX API   */        gcdZONE_NONE,
+    /* Subzones of VG API   */        gcdZONE_NONE,
+    /* -------------------- */        gcdZONE_NONE,
+    /* -------------------- */        gcdZONE_NONE,
+    /* -------------------- */        gcdZONE_NONE,
+    /* -------------------- */        gcdZONE_NONE,
+    /* -------------------- */        gcdZONE_NONE,
+    /* -------------------- */        gcdZONE_NONE,
+    /* -------------------- */        gcdZONE_NONE
 };
 
 
@@ -218,21 +201,21 @@ static gctBOOL _dumpAPIZones[16] =
 static gctUINT32 _systraceZones[16] =
 {
     /*Others*/  SYSTRACE_HAL_ZONES_EN | SYSTRACE_COMPILER_ZONE_EN,
-    /* HAL  */  gcvZONE_NONE,
-    /* EGL  */  gcvZONE_NONE,
-    /* ES11 */  gcvZONE_NONE,
-    /* ES20 */  gcvZONE_NONE,
-    /* VG11 */  gcvZONE_NONE,
-    /* GL   */  gcvZONE_NONE,
-    /* DFB  */  gcvZONE_NONE,
-    /* GDI  */  gcvZONE_NONE,
-    /* D3D  */  gcvZONE_NONE,
-    /* CL   */  gcvZONE_NONE,
-    /* VX   */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE,
-    /* ---- */  gcvZONE_NONE
+    /* HAL  */  gcdZONE_NONE,
+    /* EGL  */  gcdZONE_NONE,
+    /* ES11 */  gcdZONE_NONE,
+    /* ES20 */  gcdZONE_NONE,
+    /* VG11 */  gcdZONE_NONE,
+    /* GL   */  gcdZONE_NONE,
+    /* DFB  */  gcdZONE_NONE,
+    /* GDI  */  gcdZONE_NONE,
+    /* D3D  */  gcdZONE_NONE,
+    /* CL   */  gcdZONE_NONE,
+    /* VX   */  gcdZONE_NONE,
+    /* ---- */  gcdZONE_NONE,
+    /* ---- */  gcdZONE_NONE,
+    /* ---- */  gcdZONE_NONE,
+    /* ---- */  gcdZONE_NONE
 };
 
 /* Specify enabled API zones for systrace. */
@@ -735,12 +718,16 @@ _Print(
 
     /* Print message to buffer. */
     n = gcmVSPRINTF(buffer + i, sizeof(buffer) - i, Message, Arguments);
+    if (n > (int)sizeof(buffer) - i)
+    {
+        n = (int)sizeof(buffer) - i;
+    }
     buffer[sizeof(buffer) - 1] = '\0';
 
     if ((n <= 0) || (buffer[i + n - 1] != '\n'))
     {
         /* Append new-line. */
-        gcmSTRCAT(buffer, sizeof(buffer), "\n");
+        gcmSTRCAT(buffer, strlen("\n"), "\n\n");
         buffer[sizeof(buffer) - 1] = '\0';
     }
 
@@ -955,10 +942,6 @@ gcoOS_DebugTrace(
 **
 **      Nothing.
 */
-static void _DumpAPI(
-    IN gctUINT32 Level,
-    IN gctUINT32 Zone
-    );
 void
 gcoOS_DebugTraceZone(
     IN gctUINT32 Level,
@@ -967,10 +950,9 @@ gcoOS_DebugTraceZone(
     ...
     )
 {
-    if(Message != gcvNULL && Message[0] == '+') _DumpAPI(Level,Zone);
     /* Verify that the debug level and zone are valid. */
     if ((Level > _debugLevel)
-    ||  !(_debugZones[gcmZONE_GET_API(Zone)] & Zone & gcdZONE_MASK)
+    ||  !(_debugZones[gcmZONE_GET_API(Zone)] & Zone & gcdZONE_ALL)
     )
     {
         return;
@@ -1081,35 +1063,11 @@ gcoOS_GetDebugLevel(
     *DebugLevel = _debugLevel;
 }
 
-/*******************************************************************************
-**
-**  gcoOS_SetDebugZone
-**
-**  Set the debug zone.
-**
-**  INPUT:
-**
-**      gctUINT32 Zone
-**          New debug zone.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gcoOS_SetDebugZone(
-    IN gctUINT32 Zone
-    )
-{
-    _debugZones[gcmZONE_GET_API(Zone)] = Zone;
-}
-
 /*******************************************************************************
 **
 **  gcoOS_GetDebugZone
 **
-**  Get the current debug zone.
+**  Get current subzones of a debug API.
 **
 **  INPUT:
 **
@@ -1132,17 +1090,14 @@ gcoOS_GetDebugZone(
 
 /*******************************************************************************
 **
-**  gcoOS_SetDebugLevelZone
+**  gcoOS_SetDebugZone
 **
-**  Set the debug level and zone.
+**  Set a debug zone.
 **
 **  INPUT:
 **
-**      gctUINT32 Level
-**          New debug level.
-**
 **      gctUINT32 Zone
-**          New debug zone.
+**          A debug zone listed in gc_hal_debug_zones.h
 **
 **  OUTPUT:
 **
@@ -1150,50 +1105,28 @@ gcoOS_GetDebugZone(
 */
 
 void
-gcoOS_SetDebugLevelZone(
-    IN gctUINT32 Level,
+gcoOS_SetDebugZone(
     IN gctUINT32 Zone
     )
 {
-    _debugLevel                        = Level;
-    _debugZones[gcmZONE_GET_API(Zone)] = Zone;
-}
+    gctUINT32 _api = gcmZONE_GET_API(Zone);
+    gctUINT32 i;
 
-/*******************************************************************************
-**
-**  gcoOS_SetDebugZones
-**
-**  Enable or disable debug zones.
-**
-**  INPUT:
-**
-**      gctUINT32 Zones
-**          Debug zones to enable or disable.
-**
-**      gctBOOL Enable
-**          Set to gcvTRUE to enable the zones (or the Zones with the current
-**          zones) or gcvFALSE to disable the specified Zones.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gcoOS_SetDebugZones(
-    IN gctUINT32 Zones,
-    IN gctBOOL Enable
-    )
-{
-    if (Enable)
+    /* Zone is gcdZONE_NONE or gcdZONE_ALL */
+    if (Zone == gcdZONE_NONE || Zone == gcdZONE_ALL)
+    {
+        for(i = 0; i < gcdZONE_ARRAY_SIZE; i++)
+            _debugZones[i] = Zone;
+    }
+    /* Zone is API Zone */
+    else if (gcmZONE_GET_SUBZONES(Zone) == 0)
     {
-        /* Enable the zones. */
-        _debugZones[gcmZONE_GET_API(Zones)] |= Zones;
+        _debugZones[_api] = gcdZONE_ALL;
     }
+    /* Zone is Subzone */
     else
     {
-        /* Disable the zones. */
-        _debugZones[gcmZONE_GET_API(Zones)] &= ~Zones;
+        _debugZones[_api] |= Zone;
     }
 }
 
@@ -1229,9 +1162,6 @@ gcoOS_Verify(
 **
 **  INPUT:
 **
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
 **      gctCONST_STRING FileName
 **          Name of debug file to open or gcvNULL to close the current debug
 **          file.
@@ -1791,6 +1721,7 @@ gcoOS_StackPop(
         /* Pop arguments from the stack. */
         gcsSTACK_FRAME* frame = &traceStack->frames[--traceStack->level];
 
+
         /* Check for function mismatch. */
         if (frame->identity != Identity)
         {
@@ -1870,70 +1801,6 @@ gcoOS_StackDump(
     }
 }
 
-
-/*******************************************************************************
-**  _DumpAPI
-**
-**  Send a leveled and zoned message to the debugger.
-**
-**  INPUT:
-**
-**      gctUINT32 Level
-**          Debug level for message.
-**
-**      gctUINT32 Zone
-**          Debug zone for message.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-static void
-_DumpAPI(
-    IN gctUINT32 Level,
-    IN gctUINT32 Zone
-    )
-{
-    gcsTRACE_STACK * traceStack;
-    /* Verify that the debug level and zone are valid. */
-    if ((Level > _debugLevel)
-    ||  !(_dumpAPIZones[gcmZONE_GET_API(Zone)])
-    )
-    {
-        return;
-    }
-
-    /* Find our stack. */
-    traceStack = _FindStack();
-
-    if (traceStack == gcvNULL)
-    {
-        return;
-    }
-
-    if (traceStack->level > gcvDUMP_API_DEPTH || traceStack->level<=0)
-    {
-        return;
-    }
-    else
-    {
-        gcsSTACK_FRAME* frame = &traceStack->frames[traceStack->level-1];
-
-        gcmPRINT("  [%d] %s(%d)", traceStack->level, frame->function, frame->line);
-        if (frame->text != gcvNULL)
-        {
-            char buffer[192] = "";
-            gctUINT offset = 0;
-            gctPOINTER pointer = (gctPOINTER) frame->arguments;
-
-                gcoOS_PrintStrVSafe(buffer, gcmSIZEOF(buffer),
-                                    &offset, frame->text, *(gctARGUMENTS *) &pointer);
-            gcmPRINT("    (%s)", buffer);
-        }
-    }
-}
-
 /*******************************************************************************
 ***** Binary Trace *************************************************************
 *******************************************************************************/
index 1c31af5365a67e6fb3e2a34c554ba135b7821f16..fd0582c59c8a99a7fb9c70d952bc9b5b886c3dcd 100644 (file)
@@ -562,96 +562,6 @@ OnError:
     return status;
 }
 
-static gceSTATUS
-_MapMemory(
-    IN gctUINT32 PhysName,
-    IN gctSIZE_T NumberOfBytes,
-    OUT gctPOINTER * Logical
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("PhysName=0x%x NumberOfBytes=%lu", PhysName, NumberOfBytes);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(NumberOfBytes > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Logical != gcvNULL);
-
-    /* Call kernel API to unmap the memory. */
-    iface.ignoreTLS    = gcvTRUE;
-    iface.hardwareType = gcPLS.hal->defaultHwType,
-    iface.coreIndex    = 0;
-
-    iface.command              = gcvHAL_MAP_MEMORY;
-    iface.u.MapMemory.physName = PhysName;
-    iface.u.MapMemory.bytes    = NumberOfBytes;
-
-    gcmONERROR(gcoOS_DeviceControl(
-        gcvNULL,
-        IOCTL_GCHAL_INTERFACE,
-        &iface, gcmSIZEOF(iface),
-        &iface, gcmSIZEOF(iface)
-        ));
-
-    /* Return logical address. */
-    *Logical = gcmUINT64_TO_PTR(iface.u.MapMemory.logical);
-
-    /* Success. */
-    gcmFOOTER_ARG("*Logical=0x%x", *Logical);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-static gceSTATUS
-_UnmapMemory(
-    IN gctUINT32 PhysName,
-    IN gctSIZE_T NumberOfBytes,
-    IN gctPOINTER Logical
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("PhysName=0x%x NumberOfBytes=%lu Logical=0x%x",
-                  PhysName, NumberOfBytes, Logical);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(NumberOfBytes > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Logical != gcvNULL);
-
-    /* Call kernel API to unmap the memory. */
-    iface.ignoreTLS    = gcvTRUE;
-    iface.hardwareType = gcPLS.hal ? gcPLS.hal->defaultHwType
-                                   : gcvHARDWARE_2D;
-    iface.coreIndex    = 0;
-
-    iface.command                = gcvHAL_UNMAP_MEMORY;
-    iface.u.UnmapMemory.physName = PhysName;
-    iface.u.UnmapMemory.bytes    = NumberOfBytes;
-    iface.u.UnmapMemory.logical  = gcmPTR_TO_UINT64(Logical);
-
-    gcmONERROR(gcoOS_DeviceControl(
-        gcvNULL,
-        IOCTL_GCHAL_INTERFACE,
-        &iface, sizeof(iface),
-        &iface, sizeof(iface)
-        ));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
 static void
 _OpenGalLib(
     gcsTLS_PTR TLS
@@ -716,7 +626,8 @@ _OpenGalLib(
                 break;
             }
 
-            strncpy(envPath, path, len);
+            memset(envPath, 0, len);
+            memcpy(envPath, path, len);
             oneEnvPath = strtok_r(envPath, ":", &saveptr);
 
             while (oneEnvPath != NULL)
@@ -803,39 +714,6 @@ _PLSDestructor(
         gcPLS.destructor = gcvNULL;
     }
 
-    if (gcPLS.contiguousLogical != gcvNULL)
-    {
-        gcmVERIFY_OK(_UnmapMemory(
-            gcPLS.contiguousPhysName,
-            gcPLS.contiguousSize,
-            gcPLS.contiguousLogical
-            ));
-
-        gcPLS.contiguousLogical = gcvNULL;
-    }
-
-    if (gcPLS.externalLogical != gcvNULL)
-    {
-        gcmVERIFY_OK(_UnmapMemory(
-            gcPLS.externalPhysName,
-            gcPLS.externalSize,
-            gcPLS.externalLogical
-            ));
-
-        gcPLS.externalLogical = gcvNULL;
-    }
-
-    if (gcPLS.internalLogical != gcvNULL)
-    {
-        gcmVERIFY_OK(_UnmapMemory(
-            gcPLS.internalPhysName,
-            gcPLS.internalSize,
-            gcPLS.internalLogical
-            ));
-
-        gcPLS.internalLogical = gcvNULL;
-    }
-
 #if gcdDUMP_2D
     gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, dumpMemInfoListMutex));
     dumpMemInfoListMutex = gcvNULL;
@@ -1087,10 +965,8 @@ _ModuleConstructor(
 #endif
 
     gcmFOOTER_ARG(
-        "gcPLS.os=0x%08X, gcPLS.hal=0x%08X"
-        " internal=0x%08X external=0x%08X contiguous=0x%08X",
-        gcPLS.os, gcPLS.hal,
-        gcPLS.internalLogical, gcPLS.externalLogical, gcPLS.contiguousLogical
+        "gcPLS.os=0x%08X, gcPLS.hal=0x%08X",
+        gcPLS.os, gcPLS.hal
         );
 
     return status;
@@ -1225,36 +1101,6 @@ _OpenDevice(
         &gcPLS.contiguousSize
         ));
 
-    /* Map internal video memory. */
-    if (gcPLS.internalSize != 0)
-    {
-        gcmONERROR(_MapMemory(
-             gcPLS.internalPhysName,
-             gcPLS.internalSize,
-            &gcPLS.internalLogical
-            ));
-    }
-
-    /* Map external video memory. */
-    if (gcPLS.externalSize != 0)
-    {
-        gcmONERROR(_MapMemory(
-             gcPLS.externalPhysName,
-             gcPLS.externalSize,
-            &gcPLS.externalLogical
-            ));
-    }
-
-    /* Map contiguous video memory. */
-    if (gcPLS.contiguousSize != 0)
-    {
-        gcmONERROR(_MapMemory(
-             gcPLS.contiguousPhysName,
-             gcPLS.contiguousSize,
-            &gcPLS.contiguousLogical
-            ));
-    }
-
     /* make sure this instruction is at last */
     gcPLS.bDeviceOpen = gcvTRUE;
 
@@ -2431,7 +2277,6 @@ gcoOS_AllocateMemory(
 #if VIVANTE_PROFILER_SYSTEM_MEMORY
     if (gcPLS.bMemoryProfile)
     {
-        gcmONERROR(gcmCHECK_ADD_OVERFLOW(Bytes, VP_MALLOC_OFFSET));
         memory = malloc(Bytes + VP_MALLOC_OFFSET);
     }
     else
@@ -2491,11 +2336,12 @@ gcoOS_AllocateMemory(
     return gcvSTATUS_OK;
 
 OnError:
-    if(memory)
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
+    if (memory)
     {
         free(memory);
-        memory = gcvNULL;
     }
+#endif
 
     /* Return the status. */
     gcmFOOTER();
@@ -3245,7 +3091,6 @@ gcoOS_Read(
     OUT gctSIZE_T * ByteRead
     )
 {
-    gceSTATUS status = gcvSTATUS_OK;
     size_t byteRead;
 
     gcmHEADER_ARG("File=0x%x ByteCount=%lu Data=0x%x",
@@ -3259,31 +3104,23 @@ gcoOS_Read(
     /* Read the data from the file. */
     byteRead = fread(Data, 1, ByteCount, (FILE *) File);
 
-    if (byteRead != ByteCount)
-    {
-        if (ferror((FILE *) File))
-        {
-            status = gcvSTATUS_GENERIC_IO;
-            clearerr((FILE *) File);
-        }
-        else if (feof((FILE *) File))
-        {
-            status = gcvSTATUS_DATA_TOO_LARGE;
-            clearerr((FILE *) File);
-        }
-        else
-        {
-            status = gcvSTATUS_GENERIC_IO;
-        }
-    }
-
     if (ByteRead != gcvNULL)
     {
         *ByteRead = (gctSIZE_T) byteRead;
     }
 
-    gcmFOOTER_ARG("status=%d", status);
-    return status;
+    if (byteRead == ByteCount || ((byteRead < ByteCount) && fseek((FILE *)File, 0, SEEK_END) == 0))
+    {
+        /* Success. */
+        gcmFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
+    else
+    {
+        /* Error */
+        gcmFOOTER_NO();
+        return gcvSTATUS_GENERIC_IO;
+    }
 }
 
 /*******************************************************************************
@@ -3318,7 +3155,6 @@ gcoOS_Write(
     IN gctCONST_POINTER Data
     )
 {
-    gceSTATUS status = gcvSTATUS_OK;
     size_t byteWritten;
 
     gcmHEADER_ARG("File=0x%x ByteCount=%lu Data=0x%x",
@@ -3332,25 +3168,18 @@ gcoOS_Write(
     /* Write the data to the file. */
     byteWritten = fwrite(Data, 1, ByteCount, (FILE *) File);
 
-    if (byteWritten != ByteCount)
+    if (byteWritten == ByteCount)
     {
-        if (ferror((FILE *) File))
-        {
-            status = gcvSTATUS_GENERIC_IO;
-            clearerr((FILE *) File);
-        }
-        else if (feof((FILE *) File))
-        {
-            clearerr((FILE *) File);
-        }
-        else
-        {
-            status = gcvSTATUS_GENERIC_IO;
-        }
+        /* Success. */
+        gcmFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
+    else
+    {
+        /* Error */
+        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
+        return gcvSTATUS_GENERIC_IO;
     }
-
-    gcmFOOTER_ARG("status=%d", status);
-    return status;
 }
 
 /* Flush data to a file. */
@@ -3493,7 +3322,7 @@ gcoOS_LockFile(
 
     err = flock(fileno((FILE *)File), flags);
 
-    if (err == -1)
+    if (err)
     {
         if (errno == EWOULDBLOCK)
         {
@@ -4571,7 +4400,7 @@ gcoOS_StrCatSafe(
     IN gctCONST_STRING Source
     )
 {
-    gctSIZE_T end = 0, src = 0;
+    gctSIZE_T n;
 
     gcmHEADER_ARG("Destination=0x%x DestinationSize=%lu Source=0x%x",
                   Destination, DestinationSize, Source);
@@ -4580,31 +4409,30 @@ gcoOS_StrCatSafe(
     gcmDEBUG_VERIFY_ARGUMENT(Destination != gcvNULL);
     gcmDEBUG_VERIFY_ARGUMENT(Source != gcvNULL);
 
-    /* go to the end of destination */
-    while (Destination[end] != '\0')
+    /* Find the end of the destination. */
+#ifdef __USE_XOPEN2K8
+    n = (gctSIZE_T)strnlen(Destination, DestinationSize);
+#else
+    n = (gctSIZE_T)strlen(Destination);
+#endif
+    if (n + 1 < DestinationSize)
     {
-        end++;
-        if (end > DestinationSize)
-        {
-            return gcvSTATUS_INVALID_ARGUMENT;
-        }
-    }
+        /* Append the string but don't overflow the destination buffer. */
+        strncpy(Destination + n, Source, DestinationSize - n - 1);
 
-    /* if dest is enough to append source */
-    while (Source[src] != '\0')
+        /* Put this there in case the strncpy overflows. */
+        Destination[DestinationSize - 1] = '\0';
+
+        /* Success. */
+        gcmFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
+    else
     {
-        src++;
-        if (src > DestinationSize - end - 1)
-        {
-            return gcvSTATUS_INVALID_ARGUMENT;
-        }
+        /* Failure */
+        gcmFOOTER_NO();
+        return gcvSTATUS_DATA_TOO_LARGE;
     }
-
-    /* Append the string but don't overflow the destination buffer. */
-    strncpy(&Destination[end], Source, DestinationSize - end);
-
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
 }
 
 /*******************************************************************************
@@ -5135,10 +4963,10 @@ gcoOS_LoadLibrary(
                 ));
 
             /* Copy the library name to the temporary string buffer. */
-            strncpy(library, Library, length + 3 + 1);
+            strncpy(library, Library, length + 1);
 
             /* Append the ".so" to the temporary string buffer. */
-            strncat(library, ".so", length + 3 + 1);
+            strncat(library, ".so", 3 + 1);
 
             /* Replace the library name. */
             Library = library;
@@ -7346,6 +7174,8 @@ gcoOS_CPUPhysicalToGPUPhysical(
 void
 gcoOS_RecordAllocation(void)
 {
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
+
 #if gcdGC355_MEM_PRINT
     gcoOS os;
     if (gcPLS.os != gcvNULL)
@@ -7356,12 +7186,16 @@ gcoOS_RecordAllocation(void)
         os->oneRecording = 1;
     }
 #endif
+
+#endif
 }
 
 gctINT32
 gcoOS_EndRecordAllocation(void)
 {
     gctINT32   result = 0;
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
+
 #if gcdGC355_MEM_PRINT
     gcoOS os;
 
@@ -7378,6 +7212,8 @@ gcoOS_EndRecordAllocation(void)
         }
     }
 
+#endif
+
 #endif
     return result;
 }
@@ -7385,6 +7221,8 @@ gcoOS_EndRecordAllocation(void)
 void
 gcoOS_AddRecordAllocation(gctSIZE_T Size)
 {
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
+
 #if gcdGC355_MEM_PRINT
     gcoOS os;
 
@@ -7398,6 +7236,8 @@ gcoOS_AddRecordAllocation(gctSIZE_T Size)
         }
     }
 #endif
+
+#endif
 }
 
 gceSTATUS
index 9bff4b53259c14925628cf10ace20c958b7b0b49..86e20b5aa97ed8e3a535cb6200056cc3becbb704 100755 (executable)
@@ -87,17 +87,19 @@ endif
 # Module rules.
 
 $(TARGET_MODULE): $(OBJECTS)
-       $(AR) -r -c $@ $(OBJECTS)
+       @echo "  ARCHIVE \033[1m$(notdir $@)\033[0m"
+       @$(AR) -r -c $@ $(OBJECTS)
 ifneq ($(USE_ARMCC), 1)
-       $(RANLIB) $@
+       @$(RANLIB) $@
 endif
 
 ################################################################################
 # Object rules.
 
 $(OBJ_DIR)/%.o: %.c
+       @echo "  COMPILE $(abspath $<)"
        @mkdir -p $(OBJ_DIR)
-       $(CC) -c $(CFLAGS) -MMD -o $@ $<
+       @$(CC) -c $(CFLAGS) -MMD -o $@ $<
 
 vpath %.c platform/default
 vpath %.c platform/$(soc_vendor)
diff --git a/drivers/amlogic/npu/os/vxworks/user/gc_hal_user_os.c b/drivers/amlogic/npu/os/vxworks/user/gc_hal_user_os.c
deleted file mode 100644 (file)
index 21ed864..0000000
+++ /dev/null
@@ -1,6115 +0,0 @@
-/****************************************************************************
-*
-*    Copyright (c) 2005 - 2019 by Vivante Corp.  All rights reserved.
-*
-*    The material in this file is confidential and contains trade secrets
-*    of Vivante Corporation. This is proprietary information owned by
-*    Vivante Corporation. No part of this work may be disclosed,
-*    reproduced, copied, transmitted, or used in any way for any purpose,
-*    without the express written permission of Vivante Corporation.
-*
-*****************************************************************************/
-
-
-/**
-**  @file
-**  OS object for hal user layers.
-**
-*/
-
-#include "gc_hal_user_vxworks.h"
-#include "gc_hal_user_os_atomic.h"
-
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <pthread.h>
-
-#include "gc_hal_user_platform.h"
-
-#define _GC_OBJ_ZONE    gcvZONE_OS
-
-char const * const GALDeviceName[] =
-{
-    "/dev/galcore",
-    "/dev/graphics/galcore"
-};
-
-#define MAX_RETRY_IOCTL_TIMES 10000
-
-#ifndef gcdBUILT_FOR_VALGRIND
-#define gcdBUILT_FOR_VALGRIND 0
-#endif
-
-#define gcmGETPROCESSID() \
-    getpid()
-
-long int syscall(long int number, ...);
-#   define gcmGETTHREADID() \
-        (gctUINT32) pthread_self()
-
-
-/******************************************************************************\
-***************************** gcoOS Object Structure ***************************
-\******************************************************************************/
-
-typedef struct _gcsDRIVER_ARGS
-{
-    gctUINT64   InputBuffer;
-    gctUINT64   InputBufferSize;
-    gctUINT64   OutputBuffer;
-    gctUINT64   OutputBufferSize;
-}
-gcsDRIVER_ARGS;
-
-struct _gcoOS
-{
-    /* Object. */
-    gcsOBJECT               object;
-
-    /* Context. */
-    gctPOINTER              context;
-
-    /* Heap. */
-    gcoHEAP                 heap;
-
-    /* Base address. */
-    gctUINT32               baseAddress;
-
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-    gctUINT64               startTick;
-    gctUINT32               allocCount;
-    gctSIZE_T               allocSize;
-    gctSIZE_T               maxAllocSize;
-    gctUINT32               freeCount;
-    gctSIZE_T               freeSize;
-
-#if gcdGC355_MEM_PRINT
-    /* For a single collection. */
-    gctINT32                oneSize;
-    gctBOOL                 oneRecording;
-#endif
-#endif
-
-    gcsPLATFORM             platform;
-
-    gctUINT32               tps;
-
-    /* Handle to the device. */
-    int                     device;
-};
-
-/******************************************************************************\
-*********************************** Globals ************************************
-\******************************************************************************/
-
-static pthread_key_t gcProcessKey;
-
-gcsPLS gcPLS = gcPLS_INITIALIZER;
-static pthread_mutex_t plsMutex = PTHREAD_MUTEX_INITIALIZER;
-
-/******************************************************************************\
-****************************** Internal Functions ******************************
-\******************************************************************************/
-#if gcmIS_DEBUG(gcdDEBUG_TRACE) || gcdGC355_MEM_PRINT
-static void _ReportDB(
-    void
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcoOS_ZeroMemory(&iface, sizeof(iface));
-
-    iface.command = gcvHAL_DATABASE;
-    iface.u.Database.processID = (gctUINT32)(gctUINTPTR_T)gcoOS_GetCurrentProcessID();
-    iface.u.Database.validProcessID = gcvTRUE;
-
-    /* Call kernel service. */
-    gcmONERROR(gcoOS_DeviceControl(
-        gcvNULL,
-        IOCTL_GCHAL_INTERFACE,
-        &iface, gcmSIZEOF(iface),
-        &iface, gcmSIZEOF(iface)
-        ));
-
-    if ((iface.u.Database.vidMem.counters.bytes     != 0) ||
-        (iface.u.Database.nonPaged.counters.bytes   != 0) ||
-        (iface.u.Database.contiguous.counters.bytes != 0))
-    {
-        gcmTRACE(gcvLEVEL_ERROR, "\n");
-        gcmTRACE(gcvLEVEL_ERROR, "******* MEMORY LEAKS DETECTED *******\n");
-    }
-
-    if (iface.u.Database.vidMem.counters.bytes != 0)
-    {
-        gcmTRACE(gcvLEVEL_ERROR, "\n");
-        gcmTRACE(gcvLEVEL_ERROR, "vidMem.bytes      = %d\n", iface.u.Database.vidMem.counters.bytes);
-        gcmTRACE(gcvLEVEL_ERROR, "vidMem.maxBytes   = %d\n", iface.u.Database.vidMem.counters.maxBytes);
-        gcmTRACE(gcvLEVEL_ERROR, "vidMem.totalBytes = %d\n", iface.u.Database.vidMem.counters.totalBytes);
-    }
-
-    if (iface.u.Database.nonPaged.counters.bytes != 0)
-    {
-        gcmTRACE(gcvLEVEL_ERROR, "\n");
-        gcmTRACE(gcvLEVEL_ERROR, "nonPaged.bytes      = %d\n", iface.u.Database.nonPaged.counters.bytes);
-        gcmTRACE(gcvLEVEL_ERROR, "nonPaged.maxBytes   = %d\n", iface.u.Database.nonPaged.counters.maxBytes);
-        gcmTRACE(gcvLEVEL_ERROR, "nonPaged.totalBytes = %d\n", iface.u.Database.nonPaged.counters.totalBytes);
-    }
-
-    if (iface.u.Database.contiguous.counters.bytes != 0)
-    {
-        gcmTRACE(gcvLEVEL_ERROR, "\n");
-        gcmTRACE(gcvLEVEL_ERROR, "contiguous.bytes      = %d\n", iface.u.Database.contiguous.counters.bytes);
-        gcmTRACE(gcvLEVEL_ERROR, "contiguous.maxBytes   = %d\n", iface.u.Database.contiguous.counters.maxBytes);
-        gcmTRACE(gcvLEVEL_ERROR, "contiguous.totalBytes = %d\n", iface.u.Database.contiguous.counters.totalBytes);
-    }
-
-    gcmPRINT("05) Video memory - current : %lld \n", iface.u.Database.vidMem.counters.bytes);
-    gcmPRINT("06) Video memory - maximum : %lld \n", iface.u.Database.vidMem.counters.maxBytes);
-    gcmPRINT("07) Video memory - total   : %lld \n", iface.u.Database.vidMem.counters.totalBytes);
-    gcmPRINT("08) Video memory - allocation Count: %u \n", iface.u.Database.vidMem.counters.allocCount);
-    gcmPRINT("09) Video memory - deallocation Count : %u \n", iface.u.Database.vidMem.counters.freeCount);
-
-OnError:;
-}
-#endif
-
-#if gcdDUMP || gcdDUMP_API || gcdDUMP_2D || gcdDUMP_2DVG
-static void
-_SetDumpFileInfo(
-    )
-{
-    gceSTATUS status = gcvSTATUS_TRUE;
-    gctBOOL dumpNew2D = gcvFALSE;
-#if gcdDUMP_2D
-    gcsTLS_PTR tls;
-#endif
-
-#if gcdDUMP || gcdDUMP_2D || gcdDUMP_2DVG
-    #define DUMP_FILE_PREFIX   "hal"
-#else
-    #define DUMP_FILE_PREFIX   "api"
-#endif
-
-#if gcdDUMP_2D
-    tls = (gcsTLS_PTR) pthread_getspecific(gcProcessKey);
-
-    /* Enable new dump 2D by env variable "2D_DUMP_LEVEL". Level=2 dump all. Level=1 dump cmd only. */
-    if (status != gcvSTATUS_TRUE)
-    {
-        gctSTRING dump = gcvNULL;
-        gctINT level = 0;
-
-        if (gcmIS_SUCCESS(gcoOS_GetEnv(gcvNULL, "2D_DUMP_LEVEL", &dump)) && dump)
-        {
-            gcoOS_StrToInt(dump, &level);
-
-            if (level != 0 && level < 4)
-            {
-                tls->newDump2DFlag = level;
-                dumpNew2D = gcvTRUE;
-            }
-        }
-    }
-    else
-    {
-        tls->newDump2DFlag = 3;
-    }
-#endif
-
-    if (status == gcvSTATUS_TRUE || dumpNew2D)
-    {
-        char dump_file[128];
-        gctUINT offset = 0;
-
-        /* Customize filename as needed. */
-        gcmVERIFY_OK(gcoOS_PrintStrSafe(dump_file,
-                     gcmSIZEOF(dump_file),
-                     &offset,
-                     "%s%s_dump_pid-%d_tid-%d_%s.log",
-                     gcdDUMP_PATH,
-                     DUMP_FILE_PREFIX,
-                     gcoOS_GetCurrentProcessID(),
-                     gcmGETTHREADID(),
-                     dumpNew2D ? "dump2D" : gcdDUMP_KEY));
-
-        gcoOS_SetDebugFile(dump_file);
-        gcoDUMP_SetDumpFlag(gcvTRUE);
-    }
-}
-#endif
-
-/******************************************************************************\
-**************************** OS Construct/Destroy ******************************
-\******************************************************************************/
-static gceSTATUS
-_DestroyOs(
-    IN gcoOS Os
-    )
-{
-    gceSTATUS status;
-
-    gcmPROFILE_DECLARE_ONLY(gctUINT64 ticks);
-
-    gcmHEADER();
-
-    if (gcPLS.os != gcvNULL)
-    {
-
-        gcmPROFILE_QUERY(gcPLS.os->startTick, ticks);
-        gcmPROFILE_ONLY(gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS,
-                                      "Total ticks during gcoOS life: %llu",
-                                      ticks));
-
-        if (gcPLS.os->heap != gcvNULL)
-        {
-            gcoHEAP heap = gcPLS.os->heap;
-
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-            /* End profiler. */
-            gcoHEAP_ProfileEnd(heap, "gcoOS_HEAP");
-#endif
-
-            /* Mark the heap as gone. */
-            gcPLS.os->heap = gcvNULL;
-
-            /* Destroy the heap. */
-            gcmONERROR(gcoHEAP_Destroy(heap));
-        }
-
-        /* Close the handle to the kernel service. */
-        if (gcPLS.os->device != -1)
-        {
-#if gcmIS_DEBUG(gcdDEBUG_TRACE) || gcdGC355_MEM_PRINT
-            _ReportDB();
-#endif
-
-            close(gcPLS.os->device);
-            gcPLS.os->device = -1;
-        }
-
-#if VIVANTE_PROFILER_SYSTEM_MEMORY && gcdGC355_MEM_PRINT
-        /* End profiler. */
-        gcoOS_ProfileEnd(gcPLS.os, gcvNULL);
-#endif
-
-        /* Mark the gcoOS object as unknown. */
-        gcPLS.os->object.type = gcvOBJ_UNKNOWN;
-
-        /* Free the gcoOS structure. */
-        free(gcPLS.os);
-
-        /* Reset PLS object. */
-        gcPLS.os = gcvNULL;
-    }
-
-    /* Success. */
-    gcmFOOTER_KILL();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-static gceSTATUS
-_ConstructOs(
-    IN gctPOINTER Context,
-    OUT gcoOS * Os
-    )
-{
-    gcoOS os = gcPLS.os;
-    gceSTATUS status;
-
-    gcmPROFILE_DECLARE_ONLY(gctUINT64 freq);
-
-    gcmHEADER_ARG("Context=0x%x", Context);
-
-    if (os == gcvNULL)
-    {
-        /* Allocate the gcoOS structure. */
-        os = malloc(gcmSIZEOF(struct _gcoOS));
-        if (os == gcvNULL)
-        {
-            gcmONERROR(gcvSTATUS_OUT_OF_MEMORY);
-        }
-
-        /* Initialize the gcoOS object. */
-        os->object.type = gcvOBJ_OS;
-        os->context     = Context;
-        os->heap        = gcvNULL;
-        os->baseAddress = gcvINVALID_ADDRESS;
-        os->device      = -1;
-        os->tps         = sysClkRateGet();
-
-        /* Set the object pointer to PLS. */
-        gcmASSERT(gcPLS.os == gcvNULL);
-        gcPLS.os = os;
-
-
-        /* Construct heap. */
-        status = gcoHEAP_Construct(gcvNULL, gcdHEAP_SIZE, &os->heap);
-
-        if (gcmIS_ERROR(status))
-        {
-            gcmTRACE_ZONE(
-                gcvLEVEL_WARNING, gcvZONE_OS,
-                "%s(%d): Could not construct gcoHEAP (%d).",
-                __FUNCTION__, __LINE__, status
-                );
-
-            os->heap = gcvNULL;
-        }
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-        else
-        {
-            /* Start profiler. */
-            gcoHEAP_ProfileStart(os->heap);
-        }
-#endif
-
-        /* Get profiler start tick. */
-        gcmPROFILE_INIT(freq, os->startTick);
-
-        /* Get platform callback functions. */
-        gcoPLATFORM_QueryOperations(&os->platform.ops);
-    }
-
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-        /* Start profiler. */
-    gcoOS_ProfileStart(os);
-#endif
-
-    /* Return pointer to the gcoOS object. */
-    if (Os != gcvNULL)
-    {
-        *Os = os;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*Os=0x%x", os);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Roll back. */
-    gcmVERIFY_OK(_DestroyOs(gcvNULL));
-    gcmFOOTER();
-    return status;
-}
-
-/******************************************************************************\
-************************* Process/Thread Local Storage *************************
-\******************************************************************************/
-
-static void __attribute__((destructor)) _ModuleDestructor(void);
-static void __attribute__((constructor)) _ModuleConstructor(void);
-
-static gceSTATUS
-_QueryVideoMemory(
-    OUT gctUINT32 * InternalPhysName,
-    OUT gctSIZE_T * InternalSize,
-    OUT gctUINT32 * ExternalPhysName,
-    OUT gctSIZE_T * ExternalSize,
-    OUT gctUINT32 * ContiguousPhysName,
-    OUT gctSIZE_T * ContiguousSize
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER();
-
-    /* Call kernel HAL to query video memory. */
-    iface.ignoreTLS    = gcvTRUE;
-    iface.hardwareType = gcPLS.hal->defaultHwType,
-    iface.coreIndex    = 0;
-
-    iface.command = gcvHAL_QUERY_VIDEO_MEMORY;
-
-    /* Call kernel service. */
-    gcmONERROR(gcoOS_DeviceControl(gcvNULL,
-                                   IOCTL_GCHAL_INTERFACE,
-                                   &iface, gcmSIZEOF(iface),
-                                   &iface, gcmSIZEOF(iface)));
-
-    if (InternalPhysName != gcvNULL)
-    {
-        /* Verify arguments. */
-        gcmDEBUG_VERIFY_ARGUMENT(InternalSize != gcvNULL);
-
-        /* Save internal memory size. */
-        *InternalPhysName = iface.u.QueryVideoMemory.internalPhysName;
-        *InternalSize    = (gctSIZE_T)iface.u.QueryVideoMemory.internalSize;
-    }
-
-    if (ExternalPhysName != gcvNULL)
-    {
-        /* Verify arguments. */
-        gcmDEBUG_VERIFY_ARGUMENT(ExternalSize != gcvNULL);
-
-        /* Save external memory size. */
-        *ExternalPhysName = iface.u.QueryVideoMemory.externalPhysName;
-        *ExternalSize    = (gctSIZE_T)iface.u.QueryVideoMemory.externalSize;
-    }
-
-    if (ContiguousPhysName != gcvNULL)
-    {
-        /* Verify arguments. */
-        gcmDEBUG_VERIFY_ARGUMENT(ContiguousSize != gcvNULL);
-
-        /* Save contiguous memory size. */
-        *ContiguousPhysName = iface.u.QueryVideoMemory.contiguousPhysName;
-        *ContiguousSize    = (gctSIZE_T)iface.u.QueryVideoMemory.contiguousSize;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*InternalPhysName=0x%08x *InternalSize=%lu "
-                  "*ExternalPhysName=0x%08x *ExternalSize=%lu "
-                  "*ContiguousPhysName=0x%08x *ContiguousSize=%lu",
-                  gcmOPT_VALUE(InternalPhysName), gcmOPT_VALUE(InternalSize),
-                  gcmOPT_VALUE(ExternalPhysName), gcmOPT_VALUE(ExternalSize),
-                  gcmOPT_VALUE(ContiguousPhysName),
-                  gcmOPT_VALUE(ContiguousSize));
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-static gceSTATUS
-_MapMemory(
-    IN gctUINT32 PhysName,
-    IN gctSIZE_T NumberOfBytes,
-    OUT gctPOINTER * Logical
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("PhysName=0x%x NumberOfBytes=%lu", PhysName, NumberOfBytes);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(NumberOfBytes > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Logical != gcvNULL);
-
-    /* Call kernel API to unmap the memory. */
-    iface.ignoreTLS    = gcvTRUE;
-    iface.hardwareType = gcPLS.hal->defaultHwType,
-    iface.coreIndex    = 0;
-
-    iface.command              = gcvHAL_MAP_MEMORY;
-    iface.u.MapMemory.physName = PhysName;
-    iface.u.MapMemory.bytes    = NumberOfBytes;
-
-    gcmONERROR(gcoOS_DeviceControl(
-        gcvNULL,
-        IOCTL_GCHAL_INTERFACE,
-        &iface, gcmSIZEOF(iface),
-        &iface, gcmSIZEOF(iface)
-        ));
-
-    /* Return logical address. */
-    *Logical = gcmUINT64_TO_PTR(iface.u.MapMemory.logical);
-
-    /* Success. */
-    gcmFOOTER_ARG("*Logical=0x%x", *Logical);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-static gceSTATUS
-_UnmapMemory(
-    IN gctUINT32 PhysName,
-    IN gctSIZE_T NumberOfBytes,
-    IN gctPOINTER Logical
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("PhysName=0x%x NumberOfBytes=%lu Logical=0x%x",
-                  PhysName, NumberOfBytes, Logical);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(NumberOfBytes > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Logical != gcvNULL);
-
-    /* Call kernel API to unmap the memory. */
-    iface.ignoreTLS    = gcvTRUE;
-    iface.hardwareType = gcPLS.hal ? gcPLS.hal->defaultHwType
-                                   : gcvHARDWARE_2D;
-    iface.coreIndex    = 0;
-
-    iface.command                = gcvHAL_UNMAP_MEMORY;
-    iface.u.UnmapMemory.physName = PhysName;
-    iface.u.UnmapMemory.bytes    = NumberOfBytes;
-    iface.u.UnmapMemory.logical  = gcmPTR_TO_UINT64(Logical);
-
-    gcmONERROR(gcoOS_DeviceControl(
-        gcvNULL,
-        IOCTL_GCHAL_INTERFACE,
-        &iface, sizeof(iface),
-        &iface, sizeof(iface)
-        ));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-static void
-_PLSDestructor(
-    void
-    )
-{
-    gcmHEADER();
-
-#if gcdENABLE_3D
-#if gcdSYNC
-    if(gcPLS.globalFenceID) gcoOS_AtomDestroy(gcvNULL, gcPLS.globalFenceID);
-#endif
-#endif
-
-    if (gcPLS.destructor != gcvNULL)
-    {
-        gcPLS.destructor(&gcPLS);
-        gcPLS.destructor = gcvNULL;
-    }
-
-    if (gcPLS.contiguousLogical != gcvNULL)
-    {
-        gcmVERIFY_OK(_UnmapMemory(
-            gcPLS.contiguousPhysName,
-            gcPLS.contiguousSize,
-            gcPLS.contiguousLogical
-            ));
-
-        gcPLS.contiguousLogical = gcvNULL;
-    }
-
-    if (gcPLS.externalLogical != gcvNULL)
-    {
-        gcmVERIFY_OK(_UnmapMemory(
-            gcPLS.externalPhysName,
-            gcPLS.externalSize,
-            gcPLS.externalLogical
-            ));
-
-        gcPLS.externalLogical = gcvNULL;
-    }
-
-    if (gcPLS.internalLogical != gcvNULL)
-    {
-        gcmVERIFY_OK(_UnmapMemory(
-            gcPLS.internalPhysName,
-            gcPLS.internalSize,
-            gcPLS.internalLogical
-            ));
-
-        gcPLS.internalLogical = gcvNULL;
-    }
-
-#if gcdDUMP_2D
-    gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, dumpMemInfoListMutex));
-    dumpMemInfoListMutex = gcvNULL;
-#endif
-
-    gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.accessLock));
-    gcPLS.accessLock = gcvNULL;
-
-    gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.glFECompilerAccessLock));
-    gcPLS.glFECompilerAccessLock = gcvNULL;
-
-    gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.clFECompilerAccessLock));
-    gcPLS.clFECompilerAccessLock = gcvNULL;
-
-    gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.vxContextGlobalLock));
-    gcPLS.vxContextGlobalLock = gcvNULL;
-
-    gcmVERIFY_OK(gcoOS_AtomDestroy(gcPLS.os, gcPLS.reference));
-    gcPLS.reference = gcvNULL;
-
-    if (gcPLS.hal != gcvNULL)
-    {
-        gcmVERIFY_OK(gcoHAL_DestroyEx(gcPLS.hal));
-        gcPLS.hal = gcvNULL;
-    }
-
-    gcmVERIFY_OK(_DestroyOs(gcPLS.os));
-
-    pthread_key_delete(gcProcessKey);
-
-    gcmFOOTER_NO();
-}
-
-static void
-_TLSDestructor(
-    gctPOINTER TLS
-    )
-{
-    gcsTLS_PTR tls;
-    gctINT reference = 0;
-    gctINT i;
-
-    gcmHEADER_ARG("TLS=0x%x", TLS);
-
-    tls = (gcsTLS_PTR) TLS;
-    gcmASSERT(tls != gcvNULL);
-
-    pthread_setspecific(gcProcessKey, tls);
-
-    if (tls->copied)
-    {
-        /* Zero out all information if this TLS was copied. */
-        gcoOS_ZeroMemory(tls, gcmSIZEOF(gcsTLS));
-    }
-
-    for (i = 0; i < gcvTLS_KEY_COUNT; i++)
-    {
-        gcsDRIVER_TLS_PTR drvTLS = tls->driverTLS[i];
-
-        if (drvTLS && drvTLS->destructor != gcvNULL)
-        {
-            drvTLS->destructor(drvTLS);
-        }
-
-        tls->driverTLS[i] = gcvNULL;
-    }
-
-#if gcdENABLE_3D
-    /* DON'T destroy tls->engine3D, which belongs to app context
-    */
-#endif
-
-#if gcdUSE_VX
-    if(tls->engineVX)
-    {
-        gcmVERIFY_OK(gcoVX_Destroy(tls->engineVX));
-    }
-#endif
-
-    if (tls->defaultHardware != gcvNULL)
-    {
-        gceHARDWARE_TYPE type = tls->currentType;
-
-        tls->currentType = gcvHARDWARE_3D;
-
-        gcmTRACE_ZONE(
-            gcvLEVEL_VERBOSE, gcvZONE_HARDWARE,
-            "%s(%d): destroying default hardware object 0x%08X.",
-            __FUNCTION__, __LINE__, tls->defaultHardware
-            );
-
-        gcmVERIFY_OK(gcoHARDWARE_Destroy(tls->defaultHardware, gcvTRUE));
-
-        tls->defaultHardware = gcvNULL;
-        tls->currentHardware = gcvNULL;
-        tls->currentType = type;
-    }
-
-    if (tls->hardware2D != gcvNULL)
-    {
-        gceHARDWARE_TYPE type = tls->currentType;
-        tls->currentType = gcvHARDWARE_2D;
-
-        gcmTRACE_ZONE(
-            gcvLEVEL_VERBOSE, gcvZONE_HARDWARE,
-            "%s(%d): destroying hardware object 0x%08X.",
-            __FUNCTION__, __LINE__, tls->hardware2D
-            );
-
-        tls->hardware2D = gcvNULL;
-        tls->currentType = type;
-    }
-
-
-    if (gcPLS.reference != gcvNULL)
-    {
-        /* Decrement the reference. */
-        gcmVERIFY_OK(gcoOS_AtomDecrement(gcPLS.os,
-                                         gcPLS.reference,
-                                         &reference));
-
-        /* Check if there are still more references. */
-        if (reference ==  1)
-        {
-            /* If all threads exit, destruct PLS */
-            _PLSDestructor();
-        }
-    }
-
-    gcmVERIFY_OK(gcoOS_FreeMemory(gcvNULL, tls));
-
-    pthread_setspecific(gcProcessKey, gcvNULL);
-
-    gcmFOOTER_NO();
-}
-
-static void
-_InitializeProcess(
-    void
-    )
-{
-    /* Install thread destructor. */
-    pthread_key_create(&gcProcessKey, _TLSDestructor);
-}
-
-static gceSTATUS
-_ModuleConstructor(
-    void
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    int result;
-    static pthread_once_t onceControl = PTHREAD_ONCE_INIT;
-
-    gcmHEADER();
-
-    if (gcPLS.processID)
-    {
-        gcmFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-
-    /* Each process gets its own objects. */
-    gcmASSERT(gcPLS.os  == gcvNULL);
-    gcmASSERT(gcPLS.hal == gcvNULL);
-
-    gcmASSERT(gcPLS.internalLogical   == gcvNULL);
-    gcmASSERT(gcPLS.externalLogical   == gcvNULL);
-    gcmASSERT(gcPLS.contiguousLogical == gcvNULL);
-
-    /* Call _InitializeProcess function only one time for the process. */
-    result = pthread_once(&onceControl, _InitializeProcess);
-
-    if (result != 0)
-    {
-        gcmTRACE(
-            gcvLEVEL_ERROR,
-            "%s(%d): pthread_key_create returned %d",
-            __FUNCTION__, __LINE__, result
-            );
-
-        gcmONERROR(gcvSTATUS_OUT_OF_MEMORY);
-    }
-
-    /* Construct OS object. */
-    gcmONERROR(_ConstructOs(gcvNULL, gcvNULL));
-
-    /* Construct PLS reference atom. */
-    gcmONERROR(gcoOS_AtomConstruct(gcPLS.os, &gcPLS.reference));
-
-    /* Increment PLS reference for main thread. */
-    gcmONERROR(gcoOS_AtomIncrement(gcPLS.os, gcPLS.reference, gcvNULL));
-
-    /* Record the process and thread that calling this constructor function */
-    gcPLS.processID = gcmGETPROCESSID();
-    gcPLS.threadID = gcmGETTHREADID();
-
-    /* Construct access lock */
-    gcmONERROR(gcoOS_CreateMutex(gcPLS.os, &gcPLS.accessLock));
-
-    /* Construct gl FE compiler access lock */
-    gcmONERROR(gcoOS_CreateMutex(gcPLS.os, &gcPLS.glFECompilerAccessLock));
-
-    /* Construct cl FE compiler access lock */
-    gcmONERROR(gcoOS_CreateMutex(gcPLS.os, &gcPLS.clFECompilerAccessLock));
-
-    /* Construct vx context access lock */
-    gcmONERROR(gcoOS_CreateMutex(gcPLS.os, &gcPLS.vxContextGlobalLock));
-
-#if gcdDUMP_2D
-    gcmONERROR(gcoOS_CreateMutex(gcPLS.os, &dumpMemInfoListMutex));
-#endif
-
-    gcmFOOTER_ARG(
-        "gcPLS.os=0x%08X, gcPLS.hal=0x%08X"
-        " internal=0x%08X external=0x%08X contiguous=0x%08X",
-        gcPLS.os, gcPLS.hal,
-        gcPLS.internalLogical, gcPLS.externalLogical, gcPLS.contiguousLogical
-        );
-
-    return status;
-
-OnError:
-    if (gcPLS.accessLock != gcvNULL)
-    {
-        /* Destroy access lock */
-        gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.accessLock));
-        gcPLS.accessLock = gcvNULL;
-    }
-
-    if (gcPLS.glFECompilerAccessLock != gcvNULL)
-    {
-        /* Destroy access lock */
-        gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.glFECompilerAccessLock));
-        gcPLS.glFECompilerAccessLock = gcvNULL;
-    }
-
-    if (gcPLS.clFECompilerAccessLock != gcvNULL)
-    {
-        /* Destroy access lock */
-        gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.clFECompilerAccessLock));
-        gcPLS.clFECompilerAccessLock = gcvNULL;
-    }
-
-    if (gcPLS.vxContextGlobalLock != gcvNULL)
-    {
-        /* Destroy vx context access lock */
-        gcmVERIFY_OK(gcoOS_DeleteMutex(gcPLS.os, gcPLS.vxContextGlobalLock));
-        gcPLS.vxContextGlobalLock = gcvNULL;
-    }
-
-    if (gcPLS.reference != gcvNULL)
-    {
-        /* Destroy the reference. */
-        gcmVERIFY_OK(gcoOS_AtomDestroy(gcPLS.os, gcPLS.reference));
-        gcPLS.reference = gcvNULL;
-    }
-
-    gcmFOOTER();
-    return status;
-}
-
-static gceSTATUS
-_OpenDevice(
-    IN gcoOS Os
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gctUINT tryCount;
-
-    gcmHEADER();
-
-    pthread_mutex_lock(&plsMutex);
-
-    if (gcPLS.bDeviceOpen)
-    {
-        pthread_mutex_unlock(&plsMutex);
-        gcmFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-
-    for (tryCount = 0; tryCount < 5; tryCount++)
-    {
-        gctUINT i;
-
-        if (tryCount > 0)
-        {
-            /* Sleep for a while when second and later tries. */
-            gcoOS_Delay(Os, 1000);
-            gcmPRINT("Failed to open device: %s, Try again...", strerror(errno));
-        }
-
-        /* Attempt to open the device. */
-        for (i = 0; i < gcmCOUNTOF(GALDeviceName); i += 1)
-        {
-            gcmTRACE_ZONE(
-                gcvLEVEL_VERBOSE, gcvZONE_OS,
-                "%s(%d): Attempting to open device %s.",
-                 __FUNCTION__, __LINE__, GALDeviceName[i]
-                 );
-
-            Os->device = open(GALDeviceName[i], O_RDWR, 0);
-
-            if (Os->device >= 0)
-            {
-                gcmTRACE_ZONE(
-                    gcvLEVEL_VERBOSE, gcvZONE_OS,
-                    "%s(%d): Opened device %s.",
-                    __FUNCTION__, __LINE__, GALDeviceName[i]
-                    );
-
-                break;
-            }
-        }
-
-        if (Os->device >= 0)
-        {
-            /* Device opened. */
-            break;
-        }
-    }
-
-    if (Os->device < 0)
-    {
-        pthread_mutex_unlock(&plsMutex);
-
-        gcmPRINT(
-            "%s(%d): FATAL: Failed to open device, errno=%s.",
-            __FUNCTION__, __LINE__, strerror(errno)
-            );
-
-        exit(1);
-
-        /* Should not run here. */
-        gcmFOOTER();
-        return gcvSTATUS_GENERIC_IO;
-    }
-
-    /* Construct gcoHAL object. */
-    gcmONERROR(gcoHAL_ConstructEx(gcvNULL, gcvNULL, &gcPLS.hal));
-
-    /* Query the video memory sizes. */
-    gcmONERROR(_QueryVideoMemory(
-        &gcPLS.internalPhysName,
-        &gcPLS.internalSize,
-        &gcPLS.externalPhysName,
-        &gcPLS.externalSize,
-        &gcPLS.contiguousPhysName,
-        &gcPLS.contiguousSize
-        ));
-
-    /* Map internal video memory. */
-    if (gcPLS.internalSize != 0)
-    {
-        gcmONERROR(_MapMemory(
-             gcPLS.internalPhysName,
-             gcPLS.internalSize,
-            &gcPLS.internalLogical
-            ));
-    }
-
-    /* Map external video memory. */
-    if (gcPLS.externalSize != 0)
-    {
-        gcmONERROR(_MapMemory(
-             gcPLS.externalPhysName,
-             gcPLS.externalSize,
-            &gcPLS.externalLogical
-            ));
-    }
-
-    /* Map contiguous video memory. */
-    if (gcPLS.contiguousSize != 0)
-    {
-        gcmONERROR(_MapMemory(
-             gcPLS.contiguousPhysName,
-             gcPLS.contiguousSize,
-            &gcPLS.contiguousLogical
-            ));
-    }
-
-    /* make sure this instruction is at last */
-    gcPLS.bDeviceOpen = gcvTRUE;
-
-OnError:
-    pthread_mutex_unlock(&plsMutex);
-
-    gcmFOOTER();
-    return status;
-}
-
-static void
-_ModuleDestructor(
-    void
-    )
-{
-    gctINT reference = 0;
-    gcmHEADER();
-
-    if (gcPLS.reference != gcvNULL)
-    {
-        gcPLS.exiting = gcvTRUE;
-
-        /* Decrement the reference for main thread. */
-        gcmVERIFY_OK(gcoOS_AtomDecrement(gcPLS.os,
-                                         gcPLS.reference,
-                                         &reference));
-
-        if (reference == 1)
-        {
-            /* If all threads exit, destruct PLS. */
-            _PLSDestructor();
-        }
-        else
-        {
-            gcoOS_FreeThreadData();
-        }
-    }
-
-    gcmFOOTER_NO();
-}
-
-/******************************************************************************\
-********************************* gcoOS API Code *******************************
-\******************************************************************************/
-
-/*******************************************************************************
- **
- ** gcoOS_GetPLSValue
- **
- ** Get value associated with the given key.
- **
- ** INPUT:
- **
- **     gcePLS_VALUE key
- **         key to look up.
- **
- ** OUTPUT:
- **
- **     None
- **
- ** RETURN:
- **
- **     gctPOINTER
- **         Pointer to object associated with key.
- */
-gctPOINTER
-gcoOS_GetPLSValue(
-    IN gcePLS_VALUE key
-    )
-{
-    switch (key)
-    {
-        case gcePLS_VALUE_EGL_DISPLAY_INFO :
-            return gcPLS.eglDisplayInfo;
-
-        case gcePLS_VALUE_EGL_CONFIG_FORMAT_INFO :
-            return (gctPOINTER) gcPLS.eglConfigFormat;
-
-        case gcePLS_VALUE_EGL_DESTRUCTOR_INFO :
-            return (gctPOINTER) gcPLS.destructor;
-    }
-
-    return gcvNULL;
-}
-
-/*******************************************************************************
- **
- ** gcoOS_SetPLSValue
- **
- ** Associated object represented by 'value' with the given key.
- **
- ** INPUT:
- **
- **     gcePLS_VALUE key
- **         key to associate.
- **
- **     gctPOINTER value
- **         value to associate with key.
- **
- ** OUTPUT:
- **
- **     None
- **
- */
-void
-gcoOS_SetPLSValue(
-    IN gcePLS_VALUE key,
-    IN gctPOINTER value
-    )
-{
-    switch (key)
-    {
-        case gcePLS_VALUE_EGL_DISPLAY_INFO :
-            gcPLS.eglDisplayInfo = value;
-            return;
-
-        case gcePLS_VALUE_EGL_CONFIG_FORMAT_INFO :
-            gcPLS.eglConfigFormat = (gceSURF_FORMAT)(gctUINTPTR_T)value;
-            return;
-
-        case gcePLS_VALUE_EGL_DESTRUCTOR_INFO :
-            gcPLS.destructor = (gctPLS_DESTRUCTOR) value;
-            return;
-    }
-}
-
-static gcmINLINE gceSTATUS
-_GetTLS(
-    OUT gcsTLS_PTR * TLS
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcsTLS_PTR tls = gcvNULL;
-    int res;
-
-    if (!gcPLS.processID)
-    {
-        pthread_mutex_lock(&plsMutex);
-        status = _ModuleConstructor();
-        pthread_mutex_unlock(&plsMutex);
-
-        gcmONERROR(status);
-    }
-
-    tls = (gcsTLS_PTR) pthread_getspecific(gcProcessKey);
-
-    if (tls == NULL)
-    {
-        gcmONERROR(gcoOS_AllocateMemory(
-            gcvNULL, gcmSIZEOF(gcsTLS), (gctPOINTER *) &tls
-            ));
-
-        gcoOS_ZeroMemory(
-            tls, gcmSIZEOF(gcsTLS)
-            );
-
-        /* Determine default hardware type later. */
-        tls->currentType = gcvHARDWARE_INVALID;
-
-        res = pthread_setspecific(gcProcessKey, tls);
-
-        if (res != 0)
-        {
-            gcmTRACE(
-                gcvLEVEL_ERROR,
-                "%s(%d): pthread_setspecific returned %d",
-                __FUNCTION__, __LINE__, res
-                );
-
-            gcmONERROR(gcvSTATUS_GENERIC_IO);
-        }
-
-        if (gcPLS.reference != gcvNULL)
-        {
-            /* Increment PLS reference. */
-            gcmONERROR(gcoOS_AtomIncrement(gcPLS.os, gcPLS.reference, gcvNULL));
-        }
-
-#if gcdDUMP || gcdDUMP_API || gcdDUMP_2D || gcdDUMP_2DVG
-        _SetDumpFileInfo();
-#endif
-    }
-
-    *TLS = tls;
-
-    return gcvSTATUS_OK;
-
-OnError:
-    if (tls != gcvNULL)
-    {
-        gcmVERIFY_OK(gcoOS_FreeMemory(gcvNULL, (gctPOINTER) tls));
-    }
-
-    * TLS = gcvNULL;
-
-    return status;
-}
-
-/*******************************************************************************
- **
- ** gcoOS_GetTLS
- **
- ** Get access to the thread local storage.
- **
- ** INPUT:
- **
- **     Nothing.
- **
- ** OUTPUT:
- **
- **     gcsTLS_PTR * TLS
- **         Pointer to a variable that will hold the pointer to the TLS.
- */
-gceSTATUS
-gcoOS_GetTLS(
-    OUT gcsTLS_PTR * TLS
-    )
-{
-    gceSTATUS status;
-    gcsTLS_PTR tls = gcvNULL;
-
-    gcmONERROR(_GetTLS(&tls));
-
-    if (!gcPLS.bDeviceOpen)
-    {
-        status = _OpenDevice(gcPLS.os);
-        gcmONERROR(status);
-    }
-
-    /* Assign default hardware type. */
-    if ((tls->currentType == gcvHARDWARE_INVALID) && gcPLS.hal)
-    {
-        tls->currentType = gcPLS.hal->defaultHwType;
-    }
-
-    *TLS = tls;
-    return gcvSTATUS_OK;
-
-OnError:
-    *TLS = gcvNULL;
-    return status;
-}
-
-/*
- *  gcoOS_CopyTLS
- *
- *  Copy the TLS from a source thread and mark this thread as a copied thread, so the destructor won't free the resources.
- *
- *  NOTE: Make sure the "source thread" doesn't get kiiled while this thread is running, since the objects will be taken away. This
- *  will be fixed in a future version of the HAL when reference counters will be used to keep track of object usage (automatic
- *  destruction).
- */
-gceSTATUS gcoOS_CopyTLS(IN gcsTLS_PTR Source)
-{
-    gceSTATUS   status;
-    gcsTLS_PTR  tls;
-
-    gcmHEADER();
-
-    /* Verify the arguyments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Source != gcvNULL);
-
-    /* Get the thread specific data. */
-    tls = pthread_getspecific(gcProcessKey);
-
-    if (tls != gcvNULL)
-    {
-        /* We cannot copy if the TLS has already been initialized. */
-        gcmONERROR(gcvSTATUS_INVALID_REQUEST);
-    }
-
-    /* Allocate memory for the TLS. */
-    gcmONERROR(gcoOS_AllocateMemory(gcvNULL, gcmSIZEOF(gcsTLS), (gctPOINTER *) &tls));
-
-    /* Set the thread specific data. */
-    pthread_setspecific(gcProcessKey, tls);
-
-    if (gcPLS.reference != gcvNULL)
-    {
-        /* Increment PLS reference. */
-        gcmONERROR(gcoOS_AtomIncrement(gcPLS.os, gcPLS.reference, gcvNULL));
-    }
-
-    /* Copy the TLS information. */
-    gcoOS_MemCopy(tls, Source, sizeof(gcsTLS));
-
-    /* Mark this TLS as copied. */
-    tls->copied = gcvTRUE;
-
-    tls->currentHardware = gcvNULL;
-
-#if gcdDUMP || gcdDUMP_API || gcdDUMP_2D || gcdDUMP_2DVG
-    _SetDumpFileInfo();
-#endif
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-
-gceSTATUS
-gcoOS_QueryTLS(
-    OUT gcsTLS_PTR * TLS
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcsTLS_PTR tls;
-
-    gcmHEADER();
-
-    /* Verify the arguyments. */
-    gcmVERIFY_ARGUMENT(TLS != gcvNULL);
-
-    /* Get the thread specific data. */
-    tls = pthread_getspecific(gcProcessKey);
-
-    /* Return pointer to user. */
-    *TLS = tls;
-
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/* Get access to driver tls. */
-gceSTATUS
-gcoOS_GetDriverTLS(
-    IN gceTLS_KEY Key,
-    OUT gcsDRIVER_TLS_PTR * TLS
-    )
-{
-    gceSTATUS status;
-    gcsTLS_PTR tls;
-
-    gcmHEADER_ARG("Key=%d", Key);
-
-    if (Key >= gcvTLS_KEY_COUNT)
-    {
-        gcmONERROR(gcvSTATUS_INVALID_ARGUMENT);
-    }
-
-    /* Get generic tls. */
-    gcmONERROR(_GetTLS(&tls));
-
-    *TLS = tls->driverTLS[Key];
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/* Set driver tls. */
-gceSTATUS
-gcoOS_SetDriverTLS(
-    IN gceTLS_KEY Key,
-    IN gcsDRIVER_TLS * TLS
-    )
-{
-    gceSTATUS status;
-    gcsTLS_PTR tls;
-
-    gcmHEADER_ARG("Key=%d", Key);
-
-    if (Key >= gcvTLS_KEY_COUNT)
-    {
-        gcmONERROR(gcvSTATUS_INVALID_ARGUMENT);
-    }
-
-    /* Get generic tls. */
-    gcmONERROR(_GetTLS(&tls));
-
-    tls->driverTLS[Key] = TLS;
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-
-/*******************************************************************************
-**
-**  gcoOS_LockPLS
-**
-**  Lock mutext before access PLS if needed
-**
-**  INPUT:
-**
-**      Nothing.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_LockPLS(
-    void
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcmHEADER();
-    if (gcPLS.accessLock)
-    {
-        status = gcoOS_AcquireMutex(gcPLS.os, gcPLS.accessLock, gcvINFINITE);
-
-    }
-    gcmFOOTER_ARG("Lock PLS ret=%d", status);
-
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_UnLockPLS
-**
-**  Release mutext after access PLS if needed
-**
-**  INPUT:
-**
-**      Nothing.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_UnLockPLS(
-    void
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcmHEADER();
-    if (gcPLS.accessLock)
-    {
-        status = gcoOS_ReleaseMutex(gcPLS.os, gcPLS.accessLock);
-
-    }
-    gcmFOOTER_ARG("Release PLS ret=%d", status);
-
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_LockGLFECompiler
-**
-**  Lock mutext before access GL FE compiler if needed
-**
-**  INPUT:
-**
-**      Nothing.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_LockGLFECompiler(
-    void
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcmHEADER();
-    if (gcPLS.glFECompilerAccessLock)
-    {
-        status = gcoOS_AcquireMutex(gcPLS.os, gcPLS.glFECompilerAccessLock, gcvINFINITE);
-    }
-    gcmFOOTER_ARG("Lock GL FE compiler ret=%d", status);
-
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_UnLockGLFECompiler
-**
-**  Release mutext after access GL FE compiler if needed
-**
-**  INPUT:
-**
-**      Nothing.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_UnLockGLFECompiler(
-    void
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcmHEADER();
-    if (gcPLS.glFECompilerAccessLock)
-    {
-        status = gcoOS_ReleaseMutex(gcPLS.os, gcPLS.glFECompilerAccessLock);
-    }
-    gcmFOOTER_ARG("Release GL FE compiler ret=%d", status);
-
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_LockCLFECompiler
-**
-**  Lock mutext before access CL FE compiler if needed
-**
-**  INPUT:
-**
-**      Nothing.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_LockCLFECompiler(
-    void
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcmHEADER();
-    if (gcPLS.clFECompilerAccessLock)
-    {
-        status = gcoOS_AcquireMutex(gcPLS.os, gcPLS.clFECompilerAccessLock, gcvINFINITE);
-    }
-    gcmFOOTER_ARG("Lock CL FE compiler ret=%d", status);
-
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_UnLockCLFECompiler
-**
-**  Release mutext after access CL FE compiler if needed
-**
-**  INPUT:
-**
-**      Nothing.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_UnLockCLFECompiler(
-    void
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gcmHEADER();
-    if (gcPLS.clFECompilerAccessLock)
-    {
-        status = gcoOS_ReleaseMutex(gcPLS.os, gcPLS.clFECompilerAccessLock);
-    }
-    gcmFOOTER_ARG("Release CL FE compiler ret=%d", status);
-
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_FreeThreadData
-**
-**  Destroy the objects associated with the current thread.
-**
-**  INPUT:
-**
-**      Nothing.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-void
-gcoOS_FreeThreadData(
-    void
-    )
-{
-    gcsTLS_PTR tls;
-
-    tls = (gcsTLS_PTR) pthread_getspecific(gcProcessKey);
-
-    if (tls != NULL)
-    {
-        if (gcPLS.processID != (gctUINT32)(gctUINTPTR_T)gcmGETPROCESSID())
-        {
-            /* This process is not the one called construct function.
-             * It maybe created by fork or clone, just return in this case . */
-            return;
-        }
-
-        _TLSDestructor((gctPOINTER) tls);
-    }
-}
-
-/*******************************************************************************
- **
- ** gcoOS_Construct
- **
- ** Construct a new gcoOS object. Empty function only for compatibility.
- **
- ** INPUT:
- **
- **     gctPOINTER Context
- **         Pointer to an OS specific context.
- **
- ** OUTPUT:
- **
- **     Nothing.
- **
- */
-gceSTATUS
-gcoOS_Construct(
-    IN gctPOINTER Context,
-    OUT gcoOS * Os
-    )
-{
-    gceSTATUS status;
-    gcsTLS_PTR tls;
-
-    gcmONERROR(gcoOS_GetTLS(&tls));
-
-    /* Return gcoOS object for compatibility to prevent any failure in applications. */
-    *Os = gcPLS.os;
-
-    return gcvSTATUS_OK;
-
-OnError:
-    return status;
-}
-
-/*******************************************************************************
- **
- ** gcoOS_Destroy
- **
- ** Destroys an gcoOS object. Empty function only for compatibility.
- **
- ** ARGUMENTS:
- **
- **     gcoOS Os
- **         Pointer to the gcoOS object that needs to be destroyed.
- **
- ** OUTPUT:
- **
- **     Nothing.
- **
- */
-gceSTATUS
-gcoOS_Destroy(
-    IN gcoOS Os
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetPhysicalSystemMemorySize
-**
-**  Get the amount of system memory.
-**
-**  OUTPUT:
-**
-**      gctSIZE_T * PhysicalSystemMemorySize
-**          Pointer to a variable that will hold the size of the physical system
-**          memory.
-*/
-gceSTATUS
-gcoOS_GetPhysicalSystemMemorySize(
-    OUT gctSIZE_T * PhysicalSystemMemorySize
-    )
-{
-    return memFindMax();
-}
-
-/*******************************************************************************
-**
-**  gcoOS_QueryVideoMemory
-**
-**  Query the amount of video memory.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to a gcoOS object.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * InternalPhysName
-**          Pointer to a variable that will hold the physical memory name of the
-**          internal memory.  If 'InternalPhysName' is gcvNULL, no information
-**          about the internal memory will be returned.
-**
-**      gctSIZE_T * InternalSize
-**          Pointer to a variable that will hold the size of the internal
-**          memory.  'InternalSize' cannot be gcvNULL if 'InternalPhysName' is
-**          not gcvNULL.
-**
-**      gctUINT32 * ExternalPhysName
-**          Pointer to a variable that will hold the physical memory name of the
-**          external memory.  If 'ExternalPhysName' is gcvNULL, no information
-**          about the external memory will be returned.
-**
-**      gctSIZE_T * ExternalSize
-**          Pointer to a variable that will hold the size of the external
-**          memory.  'ExternalSize' cannot be gcvNULL if 'ExternalPhysName' is
-**          not gcvNULL.
-**
-**      gctUINT32 * ContiguousPhysName
-**          Pointer to a variable that will hold the physical memory name of the
-**          contiguous memory.  If 'ContiguousPhysName' is gcvNULL, no
-**          information about the contiguous memory will be returned.
-**
-**      gctSIZE_T * ContiguousSize
-**          Pointer to a variable that will hold the size of the contiguous
-**          memory.  'ContiguousSize' cannot be gcvNULL if 'ContiguousPhysName'
-**          is not gcvNULL.
-*/
-gceSTATUS
-gcoOS_QueryVideoMemory(
-    IN gcoOS Os,
-    OUT gctUINT32 * InternalPhysName,
-    OUT gctSIZE_T * InternalSize,
-    OUT gctUINT32 * ExternalPhysName,
-    OUT gctSIZE_T * ExternalSize,
-    OUT gctUINT32 * ContiguousPhysName,
-    OUT gctSIZE_T * ContiguousSize
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER();
-
-    /* Call kernel HAL to query video memory. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_QUERY_VIDEO_MEMORY;
-
-    /* Call kernel service. */
-    gcmONERROR(gcoOS_DeviceControl(gcvNULL,
-                                   IOCTL_GCHAL_INTERFACE,
-                                   &iface, gcmSIZEOF(iface),
-                                   &iface, gcmSIZEOF(iface)));
-
-    if (InternalPhysName != gcvNULL)
-    {
-        /* Verify arguments. */
-        gcmDEBUG_VERIFY_ARGUMENT(InternalSize != gcvNULL);
-
-        /* Save internal memory size. */
-        *InternalPhysName = iface.u.QueryVideoMemory.internalPhysName;
-        *InternalSize    = (gctSIZE_T)iface.u.QueryVideoMemory.internalSize;
-    }
-
-    if (ExternalPhysName != gcvNULL)
-    {
-        /* Verify arguments. */
-        gcmDEBUG_VERIFY_ARGUMENT(ExternalSize != gcvNULL);
-
-        /* Save external memory size. */
-        *ExternalPhysName = iface.u.QueryVideoMemory.externalPhysName;
-        *ExternalSize    = (gctSIZE_T)iface.u.QueryVideoMemory.externalSize;
-    }
-
-    if (ContiguousPhysName != gcvNULL)
-    {
-        /* Verify arguments. */
-        gcmDEBUG_VERIFY_ARGUMENT(ContiguousSize != gcvNULL);
-
-        /* Save contiguous memory size. */
-        *ContiguousPhysName = iface.u.QueryVideoMemory.contiguousPhysName;
-        *ContiguousSize    = (gctSIZE_T)iface.u.QueryVideoMemory.contiguousSize;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*InternalPhysName=0x%08x *InternalSize=%lu "
-                  "*ExternalPhysName=0x%08x *ExternalSize=%lu "
-                  "*ContiguousPhysName=0x%08x *ContiguousSize=%lu",
-                  gcmOPT_VALUE(InternalPhysName), gcmOPT_VALUE(InternalSize),
-                  gcmOPT_VALUE(ExternalPhysName), gcmOPT_VALUE(ExternalSize),
-                  gcmOPT_VALUE(ContiguousPhysName),
-                  gcmOPT_VALUE(ContiguousSize));
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetBaseAddress
-**
-**  Get the base address for the physical memory.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to the gcoOS object.
-**
-**  OUTPUT:
-**
-**      gctUINT32_PTR BaseAddress
-**          Pointer to a variable that will receive the base address.
-*/
-gceSTATUS
-gcoOS_GetBaseAddress(
-    IN gcoOS Os,
-    OUT gctUINT32_PTR BaseAddress
-    )
-{
-    gceSTATUS status;
-    gceHARDWARE_TYPE type = gcvHARDWARE_INVALID;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER();
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(BaseAddress != gcvNULL);
-
-    gcmVERIFY_OK(gcoHAL_GetHardwareType(gcvNULL, &type));
-
-    /* Return base address. */
-    if (type == gcvHARDWARE_VG)
-    {
-        *BaseAddress = 0;
-    }
-    else
-    {
-        if (gcPLS.os->baseAddress == gcvINVALID_ADDRESS)
-        {
-            /* Query base address. */
-            iface.ignoreTLS = gcvFALSE;
-            iface.command = gcvHAL_GET_BASE_ADDRESS;
-
-            /* Call kernel driver. */
-            status = gcoOS_DeviceControl(
-                gcvNULL,
-                IOCTL_GCHAL_INTERFACE,
-                &iface, gcmSIZEOF(iface),
-                &iface, gcmSIZEOF(iface)
-                );
-
-            if (gcmIS_ERROR(status))
-            {
-                gcmFOOTER();
-                return status;
-            }
-
-            gcPLS.os->baseAddress = iface.u.GetBaseAddress.baseAddress;
-        }
-
-        *BaseAddress = gcPLS.os->baseAddress;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Allocate
-**
-**  Allocate memory from the user heap.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes to allocate.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * Memory
-**          Pointer to a variable that will hold the pointer to the memory
-**          allocation.
-*/
-gceSTATUS
-gcoOS_Allocate(
-    IN gcoOS Os,
-    IN gctSIZE_T Bytes,
-    OUT gctPOINTER * Memory
-    )
-{
-    gceSTATUS status;
-
-    /*
-     * The max of all additions to Bytes in following functions,
-     * which is gcmSIZEOF(gcsHEAP) (16 bytes) + gcmSIZEOF(gcsNODE) (16 bytes)
-     */
-    gctSIZE_T bytesToAdd = 32;
-
-    gcmHEADER_ARG("Bytes=%lu", Bytes);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Bytes > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Memory != gcvNULL);
-
-    /* Make sure Bytes doesn't exceed MAX_SIZET after additions */
-    if (Bytes > gcvMAXSIZE_T - bytesToAdd)
-    {
-        gcmFOOTER_ARG("%d", gcvSTATUS_DATA_TOO_LARGE);
-        return gcvSTATUS_DATA_TOO_LARGE;
-    }
-
-    if ((gcPLS.os != gcvNULL) && (gcPLS.os->heap != gcvNULL))
-    {
-        gcmONERROR(gcoHEAP_Allocate(gcPLS.os->heap, Bytes, Memory));
-    }
-    else
-    {
-        gcmONERROR(gcoOS_AllocateMemory(gcPLS.os, Bytes, Memory));
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*Memory=0x%x", *Memory);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetMemorySize
-**
-**  Get allocated memory from the user heap.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctPOINTER  Memory
-**          Pointer to the memory
-**          allocation.
-**
-**  OUTPUT:
-**
-**      gctPOINTER MemorySize
-**          Pointer to a variable that will hold the pointer to the memory
-**          size.
-*/
-gceSTATUS
-gcoOS_GetMemorySize(
-    IN gcoOS Os,
-    IN gctPOINTER Memory,
-    OUT gctSIZE_T_PTR MemorySize
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Memory=0x%x", Memory);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Memory != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(MemorySize != gcvNULL);
-
-    /* Free the memory. */
-    if ((gcPLS.os != gcvNULL) && (gcPLS.os->heap != gcvNULL))
-    {
-        gcmONERROR(gcoHEAP_GetMemorySize(gcPLS.os->heap, Memory, MemorySize));
-    }
-    else
-    {
-        *MemorySize = 0;
-    }
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
- **
- ** gcoOS_Free
- **
- ** Free allocated memory from the user heap.
- **
- ** INPUT:
- **
- **     gcoOS Os
- **         Pointer to an gcoOS object.
- **
- **     gctPOINTER Memory
- **         Pointer to the memory allocation that needs to be freed.
- **
- ** OUTPUT:
- **
- **     Nothing.
- */
-gceSTATUS
-gcoOS_Free(
-    IN gcoOS Os,
-    IN gctPOINTER Memory
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Memory=0x%x", Memory);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Memory != gcvNULL);
-
-    /* Free the memory. */
-    if ((gcPLS.os != gcvNULL) && (gcPLS.os->heap != gcvNULL))
-    {
-        gcmONERROR(gcoHEAP_Free(gcPLS.os->heap, Memory));
-    }
-    else
-    {
-        gcmONERROR(gcoOS_FreeMemory(gcPLS.os, Memory));
-    }
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_AllocateSharedMemory
-**
-**  Allocate memory that can be used in both user and kernel.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes to allocate.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * Memory
-**          Pointer to a variable that will hold the pointer to the memory
-**          allocation.
-*/
-gceSTATUS
-gcoOS_AllocateSharedMemory(
-    IN gcoOS Os,
-    IN gctSIZE_T Bytes,
-    OUT gctPOINTER * Memory
-    )
-{
-    return gcoOS_Allocate(Os, Bytes, Memory);
-}
-
-/*******************************************************************************
- **
- ** gcoOS_FreeSharedMemory
- **
- ** Free allocated memory.
- **
- ** INPUT:
- **
- **     gcoOS Os
- **         Pointer to an gcoOS object.
- **
- **     gctPOINTER Memory
- **         Pointer to the memory allocation that needs to be freed.
- **
- ** OUTPUT:
- **
- **     Nothing.
- */
-gceSTATUS
-gcoOS_FreeSharedMemory(
-    IN gcoOS Os,
-    IN gctPOINTER Memory
-    )
-{
-    return gcoOS_Free(Os, Memory);
-}
-
-#define VP_MALLOC_OFFSET        (16)
-
-/*******************************************************************************
- **
- ** gcoOS_AllocateMemory
- **
- ** Allocate memory from the user heap.
- **
- ** INPUT:
- **
- **     gcoOS Os
- **         Pointer to an gcoOS object.
- **
- **     gctSIZE_T Bytes
- **         Number of bytes to allocate.
- **
- ** OUTPUT:
- **
- **     gctPOINTER * Memory
- **         Pointer to a variable that will hold the pointer to the memory
- **         allocation.
- */
-gceSTATUS
-gcoOS_AllocateMemory(
-    IN gcoOS Os,
-    IN gctSIZE_T Bytes,
-    OUT gctPOINTER * Memory
-    )
-{
-    gceSTATUS status;
-    gctPOINTER memory;
-
-    gcmHEADER_ARG("Bytes=%lu", Bytes);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Bytes > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Memory != gcvNULL);
-
-    /* Allocate the memory. */
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-    memory = malloc(Bytes + VP_MALLOC_OFFSET);
-#else
-    memory = malloc(Bytes);
-#endif
-
-    if (memory == gcvNULL)
-    {
-        /* Out of memory. */
-        gcmONERROR(gcvSTATUS_OUT_OF_MEMORY);
-    }
-
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-    {
-        gcoOS os = (gcPLS.os != gcvNULL) ? gcPLS.os : Os;
-
-        if (os != gcvNULL)
-        {
-            ++ (os->allocCount);
-            os->allocSize += Bytes;
-            if (os->allocSize > os->maxAllocSize)
-            {
-                os->maxAllocSize = os->allocSize;
-            }
-
-#if gcdGC355_MEM_PRINT
-            if (os->oneRecording == 1)
-            {
-                os->oneSize += (gctINT32)Bytes;
-            }
-#endif
-        }
-
-        /* Return pointer to the memory allocation. */
-        *(gctSIZE_T *) memory = Bytes;
-        *Memory = (gctPOINTER) ((gctUINT8 *) memory + VP_MALLOC_OFFSET);
-    }
-#else
-    /* Return pointer to the memory allocation. */
-    *Memory = memory;
-#endif
-
-    /* Success. */
-    gcmFOOTER_ARG("*Memory=0x%x", *Memory);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
- **
- ** gcoOS_FreeMemory
- **
- ** Free allocated memory from the user heap.
- **
- ** INPUT:
- **
- **     gcoOS Os
- **         Pointer to an gcoOS object.
- **
- **     gctPOINTER Memory
- **         Pointer to the memory allocation that needs to be freed.
- **
- ** OUTPUT:
- **
- **     Nothing.
- */
-gceSTATUS
-gcoOS_FreeMemory(
-    IN gcoOS Os,
-    IN gctPOINTER Memory
-    )
-{
-    gcmHEADER_ARG("Memory=0x%x", Memory);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Memory != gcvNULL);
-
-    /* Free the memory allocation. */
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-    {
-        gcoOS os = (gcPLS.os != gcvNULL) ? gcPLS.os : Os;
-        gctPOINTER memory;
-
-        memory = (gctUINT8 *) Memory - VP_MALLOC_OFFSET;
-
-        if (os != gcvNULL)
-        {
-#if gcdGC355_MEM_PRINT
-            if (os->oneRecording == 1)
-            {
-                os->oneSize -= (gctINT32)(*(gctSIZE_T *) memory);
-            }
-#endif
-            os->allocSize -= *(gctSIZE_T *) memory;
-            os->freeSize += *(gctSIZE_T *) memory;
-            free(memory);
-            ++ (os->freeCount);
-        }
-    }
-#else
-    free(Memory);
-#endif
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
- **
- ** gcoOS_DeviceControl
- **
- ** Perform a device I/O control call to the kernel API.
- **
- ** INPUT:
- **
- **     gcoOS Os
- **         Pointer to an gcoOS object.
- **
- **     gctUINT32 IoControlCode
- **         I/O control code to execute.
- **
- **     gctPOINTER InputBuffer
- **         Pointer to the input buffer.
- **
- **     gctSIZE_T InputBufferSize
- **         Size of the input buffer in bytes.
- **
- **     gctSIZE_T outputBufferSize
- **         Size of the output buffer in bytes.
- **
- ** OUTPUT:
- **
- **     gctPOINTER OutputBuffer
- **         Output buffer is filled with the data returned from the kernel HAL
- **         layer.
- */
-
- gceSTATUS
- gcoOS_DeviceControl(
-     IN gcoOS Os,
-     IN gctUINT32 IoControlCode,
-     IN gctPOINTER InputBuffer,
-     IN gctSIZE_T InputBufferSize,
-     OUT gctPOINTER OutputBuffer,
-     IN gctSIZE_T OutputBufferSize
-     )
- {
-     gceSTATUS status;
-     gcsHAL_INTERFACE_PTR inputBuffer;
-     gcsHAL_INTERFACE_PTR outputBuffer;
-     gcsDRIVER_ARGS args;
-     gcsTLS_PTR tls;
-     gctPOINTER logical = gcvNULL;
-     gctUINT32 interrupt_count = 0;
-
-     gcmHEADER_ARG("IoControlCode=%u InputBuffer=0x%x "
-                   "InputBufferSize=%lu OutputBuffer=0x%x OutputBufferSize=%lu",
-                   IoControlCode, InputBuffer, InputBufferSize,
-                   OutputBuffer, OutputBufferSize);
-
-     if (gcPLS.os == gcvNULL)
-     {
-         gcmONERROR(gcvSTATUS_DEVICE);
-     }
-
-     /* Cast the interface. */
-     inputBuffer  = (gcsHAL_INTERFACE_PTR) InputBuffer;
-     outputBuffer = (gcsHAL_INTERFACE_PTR) OutputBuffer;
-
-     if (!inputBuffer->ignoreTLS)
-     {
-         /* Set current hardware type */
-         if (gcPLS.processID)
-         {
-             gcmONERROR(gcoOS_GetTLS(&tls));
-             inputBuffer->hardwareType = tls->currentType;
-             inputBuffer->coreIndex = tls->currentType == gcvHARDWARE_2D ? 0 : tls->currentCoreIndex;
-         }
-         else
-         {
-             inputBuffer->hardwareType = gcvHARDWARE_2D;
-             inputBuffer->coreIndex = 0;
-         }
-     }
-
-     switch (inputBuffer->command)
-     {
-     case gcvHAL_MAP_MEMORY:
-         logical = mmap(
-             gcvNULL, inputBuffer->u.MapMemory.bytes,
-             PROT_READ | PROT_WRITE, MAP_SHARED,
-             gcPLS.os->device, (off_t) 0
-             );
-
-         if (logical != MAP_FAILED)
-         {
-             inputBuffer->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
-             inputBuffer->status = gcvSTATUS_OK;
-             gcmFOOTER_NO();
-             return gcvSTATUS_OK;
-         }
-         break;
-
-     case gcvHAL_UNMAP_MEMORY:
-         munmap(gcmUINT64_TO_PTR(inputBuffer->u.UnmapMemory.logical), inputBuffer->u.UnmapMemory.bytes);
-
-         inputBuffer->status = gcvSTATUS_OK;
-         gcmFOOTER_NO();
-         return gcvSTATUS_OK;
-
-     default:
-         /* This has to be here so that GCC does not complain. */
-         break;
-     }
-
-     /* Call kernel. */
-     args.InputBuffer       = gcmPTR_TO_UINT64(InputBuffer);
-     args.InputBufferSize  = InputBufferSize;
-     args.OutputBuffer       = gcmPTR_TO_UINT64(OutputBuffer);
-     args.OutputBufferSize = OutputBufferSize;
-
-     while (ioctl(gcPLS.os->device, IoControlCode, &args) < 0)
-     {
-         if (errno != EINTR)
-         {
-             gcmTRACE(gcvLEVEL_ERROR, "ioctl failed; errno=%s\n", strerror(errno));
-             gcmONERROR(gcvSTATUS_GENERIC_IO);
-         }
-         /* Retry MAX_RETRY_IOCTL_TIMES times at most when receiving interrupt */
-         else if (++interrupt_count == MAX_RETRY_IOCTL_TIMES)
-         {
-             gcmTRACE(gcvLEVEL_ERROR, "ioctl failed; too many interrupt\n");
-             gcmONERROR(gcvSTATUS_GENERIC_IO);
-         }
-     }
-
-     /* Get the status. */
-     status = outputBuffer->status;
-
-     /* Eliminate gcmONERROR on gcoOS_WaitSignal timeout errors. */
-#if gcmIS_DEBUG(gcdDEBUG_CODE)
-     if ((inputBuffer->command == gcvHAL_USER_SIGNAL) &&
-         (inputBuffer->u.UserSignal.command == gcvUSER_SIGNAL_WAIT))
-     {
-         if (status == gcvSTATUS_TIMEOUT)
-         {
-             goto OnError;
-         }
-     }
-#endif
-
-     /* Test for API error. */
-     gcmONERROR(status);
-
-OnError:
-     /* Return the status. */
-     gcmFOOTER();
-     return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Open
-**
-**  Open or create a file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctCONST_STRING FileName
-**          File name of file to open or create.
-**
-**      gceFILE_MODE Mode
-**          Mode to open file with:
-**
-**              gcvFILE_CREATE      - Overwite any existing file.
-**              gcvFILE_APPEND      - Append to an exisiting file or create a
-**                                    new file if there is no exisiting file.
-**              gcvFILE_READ        - Open an existing file for read only.
-**              gcvFILE_CREATETEXT  - Overwite any existing text file.
-**              gcvFILE_APPENDTEXT  - Append to an exisiting text file or create
-**                                    a new text file if there is no exisiting
-**                                    file.
-**              gcvFILE_READTEXT    - Open an existing text file fir read only.
-**
-**  OUTPUT:
-**
-**      gctFILE * File
-**          Pointer to a variable receivig the handle to the opened file.
-*/
-gceSTATUS
-gcoOS_Open(
-    IN gcoOS Os,
-    IN gctCONST_STRING FileName,
-    IN gceFILE_MODE Mode,
-    OUT gctFILE * File
-    )
-{
-    static gctCONST_STRING modes[] =
-    {
-        "wb",
-        "ab",
-        "rb",
-        "w",
-        "a",
-        "r",
-    };
-    FILE * file;
-
-    gcmHEADER_ARG("FileName=%s Mode=%d",
-                  gcmOPT_STRING(FileName), Mode);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(File != gcvNULL);
-
-    /* Open the file. */
-    file = fopen(FileName, modes[Mode]);
-
-    if (file == gcvNULL)
-    {
-        /* Error. */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-        return gcvSTATUS_GENERIC_IO;
-    }
-
-    /* Return handle to file. */
-    *File = (gctFILE) file;
-
-    /* Success. */
-    gcmFOOTER_ARG("*File=0x%x", *File);
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Close
-**
-**  Close a file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_Close(
-    IN gcoOS Os,
-    IN gctFILE File
-    )
-{
-    gcmHEADER_ARG("File=0x%x", File);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(File != gcvNULL);
-
-    /* Close the file. */
-    fclose((FILE *) File);
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Read
-**
-**  Read data from an open file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**      gctSIZE_T ByteCount
-**          Number of bytes to read from the file.
-**
-**      gctCONST_POINTER Data
-**          Pointer to the data to read from the file.
-**
-**  OUTPUT:
-**
-**      gctSIZE_T * ByteRead
-**          Pointer to a variable receiving the number of bytes read from the
-**          file.
-*/
-gceSTATUS
-gcoOS_Read(
-    IN gcoOS Os,
-    IN gctFILE File,
-    IN gctSIZE_T ByteCount,
-    IN gctPOINTER Data,
-    OUT gctSIZE_T * ByteRead
-    )
-{
-    size_t byteRead;
-
-    gcmHEADER_ARG("File=0x%x ByteCount=%lu Data=0x%x",
-                  File, ByteCount, Data);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(File != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(ByteCount > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Data != gcvNULL);
-
-    /* Read the data from the file. */
-    byteRead = fread(Data, 1, ByteCount, (FILE *) File);
-
-    if (ByteRead != gcvNULL)
-    {
-        *ByteRead = (gctSIZE_T) byteRead;
-        /* Success. */
-        gcmFOOTER_ARG("*ByteRead=%lu", gcmOPT_VALUE(ByteRead));
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        /* Failure. */
-        gcmFOOTER_ARG("%d", gcvSTATUS_TRUE);
-        return gcvSTATUS_TRUE;
-    }
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Write
-**
-**  Write data to an open file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**      gctSIZE_T ByteCount
-**          Number of bytes to write to the file.
-**
-**      gctCONST_POINTER Data
-**          Pointer to the data to write to the file.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_Write(
-    IN gcoOS Os,
-    IN gctFILE File,
-    IN gctSIZE_T ByteCount,
-    IN gctCONST_POINTER Data
-    )
-{
-    size_t byteWritten;
-
-    gcmHEADER_ARG("File=0x%x ByteCount=%lu Data=0x%x",
-                  File, ByteCount, Data);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(File != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(ByteCount > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Data != gcvNULL);
-
-    /* Write the data to the file. */
-    byteWritten = fwrite(Data, 1, ByteCount, (FILE *) File);
-
-    if (byteWritten == ByteCount)
-    {
-        /* Success. */
-        gcmFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        /* Error */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-        return gcvSTATUS_GENERIC_IO;
-    }
-}
-
-/* Flush data to a file. */
-gceSTATUS
-gcoOS_Flush(
-    IN gcoOS Os,
-    IN gctFILE File
-    )
-{
-    gcmHEADER_ARG("File=0x%x", File);
-
-    fflush((FILE *) File);
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gcoOS_FscanfI(
-    IN gcoOS Os,
-    IN gctFILE File,
-    IN gctCONST_STRING Format,
-    OUT gctUINT *result
-    )
-{
-    gctINT ret;
-    gcmHEADER_ARG("File=0x%x Format=0x%x", File, Format);
-
-    /* Verify the arguments. */
-    gcmVERIFY_ARGUMENT(File != gcvNULL);
-    gcmVERIFY_ARGUMENT(Format != gcvNULL);
-
-    /* Format the string. */
-    ret = fscanf(File, Format, result);
-
-    if (!ret)
-    {
-        gcmFOOTER_NO();
-        return gcvSTATUS_GENERIC_IO;
-    }
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gcoOS_DupFD(
-    IN gcoOS Os,
-    IN gctINT FD,
-    OUT gctINT * FD2
-    )
-{
-    int fd;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("FD=%d", FD);
-    fd = dup(FD);
-
-    if (fd < 0)
-    {
-        status = gcvSTATUS_OUT_OF_RESOURCES;
-        gcmFOOTER();
-        return status;
-    }
-
-    *FD2 = fd;
-    gcmFOOTER_ARG("FD2=%d", FD2);
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gcoOS_CloseFD(
-    IN gcoOS Os,
-    IN gctINT FD
-    )
-{
-    int err;
-    gceSTATUS status;
-    gcmHEADER_ARG("FD=%d", FD);
-
-    err = close(FD);
-
-    if (err < 0)
-    {
-        status = gcvSTATUS_GENERIC_IO;
-        gcmFOOTER();
-        return status;
-    }
-
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_LockFile
-**
-**  Apply an advisory lock on an open file
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**      gctBOOL Shared
-**          Place a shared lock if true. More than one process may hold a
-**          shared lock for a given file at a given time.
-**          Place an exclusive lock. Only one process may hold an exclusive
-**          lock for a given file at a given time.
-**
-**      gctBOOL Block
-**          Block if an incompatible lock is held by another process.
-**          Otherwise return immediately with gcvSTATUS_LOCKED error.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_LockFile(
-    IN gcoOS Os,
-    IN gctFILE File,
-    IN gctBOOL Shared,
-    IN gctBOOL Block
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_UnlockFile
-**
-**  Remove an advisory lock on an open file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_UnlockFile(
-    IN gcoOS Os,
-    IN gctFILE File
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-
-/* Create an endpoint for communication. */
-gceSTATUS
-gcoOS_Socket(
-    IN gcoOS Os,
-    IN gctINT Domain,
-    IN gctINT Type,
-    IN gctINT Protocol,
-    OUT gctINT * SockFd
-    )
-{
-    gctINT fd;
-
-    gcmHEADER_ARG("Domain=%d Type=%d Protocol=%d",
-                  Domain, Type, Protocol);
-
-    /* Create a socket. */
-    fd = socket(Domain, Type, Protocol);
-
-    if (fd >= 0)
-    {
-        /* Return socket descriptor. */
-        *SockFd = fd;
-
-        /* Success. */
-        gcmFOOTER_ARG("*SockFd=%d", *SockFd);
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        /* Error. */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-        return gcvSTATUS_GENERIC_IO;
-    }
-}
-
-/* Close a socket. */
-gceSTATUS
-gcoOS_WaitForSend(
-    IN gcoOS Os,
-    IN gctINT SockFd,
-    IN gctINT Seconds,
-    IN gctINT MicroSeconds
-    )
-{
-    gcmHEADER_ARG("SockFd=%d Seconds=%d MicroSeconds=%d",
-                  SockFd, Seconds, MicroSeconds);
-
-    struct timeval tv;
-    fd_set writefds;
-    int ret;
-
-    tv.tv_sec  = Seconds;
-    tv.tv_usec = MicroSeconds;
-
-    FD_ZERO(&writefds);
-    FD_SET(SockFd, &writefds);
-
-    ret = select(SockFd + 1, NULL, &writefds, NULL, &tv);
-
-    if (ret == 0)
-    {
-        /* Timeout. */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT);
-        return gcvSTATUS_TIMEOUT;
-    }
-    else if (ret == -1)
-    {
-        /* Error. */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-        return gcvSTATUS_GENERIC_IO;
-    }
-    else
-    {
-        int error = 0;
-        int len = sizeof(error);
-
-        /* Get error code. */
-        getsockopt(SockFd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
-
-        if (! error)
-        {
-            /* Success. */
-            gcmFOOTER_NO();
-            return gcvSTATUS_OK;
-        }
-    }
-
-    /* Error */
-    gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-    return gcvSTATUS_GENERIC_IO;
-}
-
-/* Close a socket. */
-gceSTATUS
-gcoOS_CloseSocket(
-    IN gcoOS Os,
-    IN gctINT SockFd
-    )
-{
-    gcmHEADER_ARG("SockFd=%d", SockFd);
-
-    /* Close the socket file descriptor. */
-    gcoOS_WaitForSend(gcvNULL, SockFd, 600, 0);
-    close(SockFd);
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/* Initiate a connection on a socket. */
-gceSTATUS
-gcoOS_Connect(
-    IN gcoOS Os,
-    IN gctINT SockFd,
-    IN gctCONST_POINTER HostName,
-    IN gctUINT Port
-    )
-{
-    gctINT rc;
-    gctINT addrLen;
-    struct sockaddr sockAddr;
-    struct sockaddr_in *sockAddrIn;
-    struct in_addr *inAddr;
-
-    gcmHEADER_ARG("SockFd=0x%x HostName=0x%x Port=%d",
-                  SockFd, HostName, Port);
-
-    /* Get server address. */
-    sockAddrIn = (struct sockaddr_in *) &sockAddr;
-    sockAddrIn->sin_family = AF_INET;
-    inAddr = &sockAddrIn->sin_addr;
-    inAddr->s_addr = inet_addr(HostName);
-
-    /* If it is a numeric host name, convert it now */
-    if (inAddr->s_addr == INADDR_NONE)
-    {
-#if !gcdSTATIC_LINK
-        struct hostent *hostEnt;
-        struct in_addr *arrayAddr;
-
-        /* It is a real name, we solve it */
-        if ((hostEnt = gethostbyname(HostName)) == NULL)
-        {
-            /* Error */
-            gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-            return gcvSTATUS_GENERIC_IO;
-        }
-        arrayAddr = (struct in_addr *) *(hostEnt->h_addr_list);
-        inAddr->s_addr = arrayAddr[0].s_addr;
-#endif /*gcdSTATIC_LINK*/
-    }
-
-    sockAddrIn->sin_port = htons((gctUINT16) Port);
-
-    /* Currently, for INET only. */
-    addrLen = sizeof(struct sockaddr);
-
-    /*{
-    gctINT arg = 1;
-    ioctl(SockFd, FIONBIO, &arg);
-    }*/
-
-    /* Close the file descriptor. */
-    rc = connect(SockFd, &sockAddr, addrLen);
-
-    if (rc)
-    {
-        int err = errno;
-
-        if (err == EINPROGRESS)
-        {
-            gceSTATUS status;
-
-            /* Connect is not complete.  Wait for it. */
-            status = gcoOS_WaitForSend(gcvNULL, SockFd, 600, 0);
-
-            gcmFOOTER();
-            return status;
-        }
-
-        /* Error */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-        return gcvSTATUS_GENERIC_IO;
-    }
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/* Shut down part of connection on a socket. */
-gceSTATUS
-gcoOS_Shutdown(
-    IN gcoOS Os,
-    IN gctINT SockFd,
-    IN gctINT How
-    )
-{
-    gcmHEADER_ARG("SockFd=%d How=%d", SockFd, How);
-
-    /* Shut down connection. */
-    shutdown(SockFd, How);
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/* Send a message on a socket. */
-gceSTATUS
-gcoOS_Send(
-    IN gcoOS Os,
-    IN gctINT SockFd,
-    IN gctSIZE_T ByteCount,
-    IN gctCONST_POINTER Data,
-    IN gctINT Flags
-    )
-{
-    gctINT byteSent;
-
-    gcmHEADER_ARG("SockFd=0x%x ByteCount=%lu Data=0x%x Flags=%d",
-                  SockFd, ByteCount, Data, Flags);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(ByteCount > 0);
-    gcmDEBUG_VERIFY_ARGUMENT(Data != gcvNULL);
-
-    /* Write the data to the file. */
-    /*gcoOS_WaitForSend(gcvNULL, SockFd, 0, 50000);*/
-    byteSent = send(SockFd, Data, ByteCount, Flags);
-
-    if (byteSent == (gctINT) ByteCount)
-    {
-        /* Success. */
-        gcmFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        /* Error */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-        return gcvSTATUS_GENERIC_IO;
-    }
-}
-
-/* Get environment variable value. */
-gceSTATUS
-gcoOS_GetEnv(
-    IN gcoOS Os,
-    IN gctCONST_STRING VarName,
-    OUT gctSTRING * Value
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/* Set environment variable value. */
-gceSTATUS gcoOS_SetEnv(
-    IN gcoOS Os,
-    IN gctCONST_STRING VarName,
-    IN gctSTRING Value
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/* Get current working directory. */
-gceSTATUS
-gcoOS_GetCwd(
-    IN gcoOS Os,
-    IN gctINT SizeInBytes,
-    OUT gctSTRING Buffer
-    )
-{
-    gcmHEADER_ARG("SizeInBytes=%d", SizeInBytes);
-
-    if (getcwd(Buffer, SizeInBytes))
-    {
-        gcmFOOTER_ARG("Buffer=%s", Buffer);
-        return gcvSTATUS_NOT_SUPPORTED;
-    }
-    else
-    {
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_NOT_SUPPORTED);
-        return gcvSTATUS_NOT_SUPPORTED;
-    }
-}
-
-/* Get file status info. */
-gceSTATUS
-gcoOS_Stat(
-    IN gcoOS Os,
-    IN gctCONST_STRING FileName,
-    OUT gctPOINTER Buffer
-    )
-{
-    gcmHEADER_ARG("FileName=%s", gcmOPT_STRING(FileName));
-
-    if (stat(FileName, Buffer) == 0)
-    {
-        gcmFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_NOT_SUPPORTED);
-        return gcvSTATUS_NOT_SUPPORTED;
-    }
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetPos
-**
-**  Get the current position of a file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Position
-**          Pointer to a variable receiving the current position of the file.
-*/
-gceSTATUS
-gcoOS_GetPos(
-    IN gcoOS Os,
-    IN gctFILE File,
-    OUT gctUINT32 * Position
-    )
-{
-    gctINT64 ret;
-    gcmHEADER_ARG("File=0x%x", File);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(File != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Position != gcvNULL);
-
-    /* Get the current file position. */
-    ret = ftell((FILE *) File);
-
-    /* Check if ftell encounters error. */
-    if (ret == -1)
-    {
-        gcmFOOTER_ARG("%d", gcvSTATUS_TRUE);
-        return gcvSTATUS_TRUE;
-    }
-    /* If no error, ret contains a file size of a positive number.
-       Check if this file size is supported.
-       Since file size will be stored in UINT32, up to 2^32 = 4Gb is supported.
-    */
-    else if (ret >= gcvMAXUINT32)
-    {
-        gcmFOOTER_ARG("%d", gcvSTATUS_DATA_TOO_LARGE);
-        return gcvSTATUS_DATA_TOO_LARGE;
-    }
-    else
-    {
-        /* Now we're sure file size takes <= 32 bit and cast it to UINT32 safely. */
-        *Position = (gctUINT32) ret;
-
-        gcmFOOTER_ARG("*Position=%u", *Position);
-        return gcvSTATUS_OK;
-    }
-}
-
-/*******************************************************************************
-**
-**  gcoOS_SetPos
-**
-**  Set position for a file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**      gctUINT32 Position
-**          Absolute position of the file to set.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_SetPos(
-    IN gcoOS Os,
-    IN gctFILE File,
-    IN gctUINT32 Position
-    )
-{
-    gcmHEADER_ARG("File=0x%x Position=%u", File, Position);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(File != gcvNULL);
-
-    /* Set file position. */
-    fseek((FILE *) File, Position, SEEK_SET);
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Seek
-**
-**  Set position for a file.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctFILE File
-**          Pointer to an open file object.
-**
-**      gctUINT32 Offset
-**          Offset added to the position specified by Whence.
-**
-**      gceFILE_WHENCE Whence
-**          Mode that specify how to add the offset to the position:
-**
-**              gcvFILE_SEEK_SET    - Relative to the start of the file.
-**              gcvFILE_SEEK_CUR    - Relative to the current position.
-**              gcvFILE_SEEK_END    - Relative to the end of the file.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_Seek(
-    IN gcoOS Os,
-    IN gctFILE File,
-    IN gctUINT32 Offset,
-    IN gceFILE_WHENCE Whence
-    )
-{
-    gctINT result = 0;
-
-    gcmHEADER_ARG("File=0x%x Offset=%u Whence=%d",
-                  File, Offset, Whence);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(File != gcvNULL);
-
-    /* Set file position. */
-    switch (Whence)
-    {
-    case gcvFILE_SEEK_SET:
-        result = fseek((FILE *) File, Offset, SEEK_SET);
-        break;
-
-    case gcvFILE_SEEK_CUR:
-        result = fseek((FILE *) File, Offset, SEEK_CUR);
-        break;
-
-    case gcvFILE_SEEK_END:
-        result = fseek((FILE *) File, Offset, SEEK_END);
-        break;
-    }
-
-    if (result == 0)
-    {
-        /* Success. */
-        gcmFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        /* Error */
-        gcmFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
-        return gcvSTATUS_GENERIC_IO;
-    }
-}
-
-/*******************************************************************************
-**
-**  gcoOS_CreateThread
-**
-**  Create a new thread.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * Thread
-**          Pointer to a variable that will hold a pointer to the thread.
-*/
-gceSTATUS
-gcoOS_CreateThread(
-    IN gcoOS Os,
-    IN gcTHREAD_ROUTINE Worker,
-    IN gctPOINTER Argument,
-    OUT gctPOINTER * Thread
-    )
-{
-    pthread_t thread;
-
-    gcmHEADER_ARG("Worker=0x%x Argument=0x%x", Worker, Argument);
-
-    /* Validate the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Thread != gcvNULL);
-
-    thread = taskSpawn("display", 120, 0, 1024*1024, (FUNCPTR)Worker,
-             Argument, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
-    *Thread = (gctPOINTER) thread;
-
-    /* Success. */
-    gcmFOOTER_ARG("*Thread=0x%x", *Thread);
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_CloseThread
-**
-**  Close a thread.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctPOINTER Thread
-**          Pointer to the thread to be deleted.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_CloseThread(
-    IN gcoOS Os,
-    IN gctPOINTER Thread
-    )
-{
-    gcmHEADER_ARG("Thread=0x%x", Thread);
-
-    /* Validate the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Thread != gcvNULL);
-
-    pthread_join((pthread_t) Thread, gcvNULL);
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_CreateMutex
-**
-**  Create a new mutex.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * Mutex
-**          Pointer to a variable that will hold a pointer to the mutex.
-*/
-gceSTATUS
-gcoOS_CreateMutex(
-    IN gcoOS Os,
-    OUT gctPOINTER * Mutex
-    )
-{
-    gceSTATUS status;
-    pthread_mutex_t* mutex;
-    pthread_mutexattr_t   mta;
-
-    gcmHEADER();
-
-    /* Validate the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Mutex != gcvNULL);
-
-    /* Allocate memory for the mutex. */
-    gcmONERROR(gcoOS_Allocate(
-        gcvNULL, gcmSIZEOF(pthread_mutex_t), (gctPOINTER *) &mutex
-        ));
-
-    pthread_mutexattr_init(&mta);
-
-    /* Initialize the mutex. */
-    pthread_mutex_init(mutex, &mta);
-
-    /* Destroy mta.*/
-    pthread_mutexattr_destroy(&mta);
-
-    /* Return mutex to caller. */
-    *Mutex = (gctPOINTER) mutex;
-
-    /* Success. */
-    gcmFOOTER_ARG("*Mutex = 0x%x", *Mutex);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_DeleteMutex
-**
-**  Delete a mutex.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctPOINTER Mutex
-**          Pointer to the mutex to be deleted.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_DeleteMutex(
-    IN gcoOS Os,
-    IN gctPOINTER Mutex
-    )
-{
-    pthread_mutex_t *mutex;
-
-    gcmHEADER_ARG("Mutex=0x%x", Mutex);
-
-    /* Validate the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Mutex != gcvNULL);
-
-    /* Cast the pointer. */
-    mutex = (pthread_mutex_t *) Mutex;
-
-    /* Destroy the mutex. */
-    pthread_mutex_destroy(mutex);
-
-    /* Free the memory. */
-    gcmVERIFY_OK(gcmOS_SAFE_FREE(gcvNULL, mutex));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_AcquireMutex
-**
-**  Acquire a mutex.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctPOINTER Mutex
-**          Pointer to the mutex to be acquired.
-**
-**      gctUINT32 Timeout
-**          Timeout value specified in milliseconds.
-**          Specify the value of gcvINFINITE to keep the thread suspended
-**          until the mutex has been acquired.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_AcquireMutex(
-    IN gcoOS Os,
-    IN gctPOINTER Mutex,
-    IN gctUINT32 Timeout
-    )
-{
-    gceSTATUS status;
-    pthread_mutex_t *mutex;
-
-    gcmHEADER_ARG("Mutex=0x%x Timeout=%u", Mutex, Timeout);
-
-    /* Validate the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Mutex != gcvNULL);
-
-    /* Cast the pointer. */
-    mutex = (pthread_mutex_t *) Mutex;
-
-    /* Test for infinite. */
-    if (Timeout == gcvINFINITE)
-    {
-        /* Lock the mutex. */
-        if (pthread_mutex_lock(mutex))
-        {
-            /* Some error. */
-            status = gcvSTATUS_GENERIC_IO;
-        }
-        else
-        {
-            /* Success. */
-            status = gcvSTATUS_OK;
-        }
-    }
-    else
-    {
-        /* Try locking the mutex. */
-        if (pthread_mutex_trylock(mutex))
-        {
-            /* Assume timeout. */
-            status = gcvSTATUS_TIMEOUT;
-
-            /* Loop while not timeout. */
-            while (Timeout-- > 0)
-            {
-                /* Try locking the mutex. */
-                if (pthread_mutex_trylock(mutex) == 0)
-                {
-                    /* Success. */
-                    status = gcvSTATUS_OK;
-                    break;
-                }
-
-                /* Sleep 1 millisecond. */
-                gcoOS_Delay(Os, 1);
-            }
-        }
-        else
-        {
-            /* Success. */
-            status = gcvSTATUS_OK;
-        }
-    }
-
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_ReleaseMutex
-**
-**  Release an acquired mutex.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctPOINTER Mutex
-**          Pointer to the mutex to be released.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_ReleaseMutex(
-    IN gcoOS Os,
-    IN gctPOINTER Mutex
-    )
-{
-    pthread_mutex_t *mutex;
-
-    gcmHEADER_ARG("Mutex=0x%x", Mutex);
-
-    /* Validate the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Mutex != gcvNULL);
-
-    /* Cast the pointer. */
-    mutex = (pthread_mutex_t *) Mutex;
-
-    /* Release the mutex. */
-    pthread_mutex_unlock(mutex);
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Delay
-**
-**  Delay execution of the current thread for a number of milliseconds.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctUINT32 Delay
-**          Delay to sleep, specified in milliseconds.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_Delay(
-    IN gcoOS Os,
-    IN gctUINT32 Delay
-    )
-{
-    gctUINT32 ticksPerSecond = Os->tps;
-    gctUINT32 ticks = 0;
-
-    gcmHEADER_ARG("Os=0x%X Delay=%u", Os, Delay);
-
-    if (Delay > 0)
-    {
-        ticksPerSecond = 1000 / ticksPerSecond;
-        ticks = Delay / ticksPerSecond + 1;
-
-        taskDelay(ticks);
-    }
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gcoOS_StrStr(
-    IN gctCONST_STRING String,
-    IN gctCONST_STRING SubString,
-    OUT gctSTRING * Output
-    )
-{
-    gctCHAR* pos;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("String=0x%x SubString=0x%x", String, SubString);
-
-    /* Verify the arguments. */
-    gcmVERIFY_ARGUMENT(String != gcvNULL);
-    gcmVERIFY_ARGUMENT(SubString != gcvNULL);
-
-    /* Call C. */
-    pos = strstr(String, SubString);
-    if (Output)
-    {
-        *Output = pos;
-    }
-    status = pos ? gcvSTATUS_TRUE : gcvSTATUS_FALSE;
-
-    /* Success. */
-    gcmFOOTER();
-    return status;
-}
-
-gceSTATUS
-gcoOS_StrFindReverse(
-    IN gctCONST_STRING String,
-    IN gctINT8 Character,
-    OUT gctSTRING * Output
-    )
-{
-    gcmHEADER_ARG("String=0x%x Character=%d", String, Character);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(String != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Output != gcvNULL);
-
-    /* Call C. */
-    *Output = strrchr(String, Character);
-
-    /* Success. */
-    gcmFOOTER_ARG("*Output=0x%x", *Output);
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_StrCopy
-**
-**  Copy a string.
-**
-**  INPUT:
-**
-**      gctSTRING Destination
-**          Pointer to the destination string.
-**
-**      gctCONST_STRING Source
-**          Pointer to the source string.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_StrCopySafe(
-    IN gctSTRING Destination,
-    IN gctSIZE_T DestinationSize,
-    IN gctCONST_STRING Source
-    )
-{
-    gcmHEADER_ARG("Destination=0x%x DestinationSize=%lu Source=0x%x",
-                  Destination, DestinationSize, Source);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Destination != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Source != gcvNULL);
-
-    /* Don't overflow the destination buffer. */
-    strncpy(Destination, Source, DestinationSize - 1);
-
-    /* Put this there in case the strncpy overflows. */
-    Destination[DestinationSize - 1] = '\0';
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_StrCat
-**
-**  Append a string.
-**
-**  INPUT:
-**
-**      gctSTRING Destination
-**          Pointer to the destination string.
-**
-**      gctCONST_STRING Source
-**          Pointer to the source string.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_StrCatSafe(
-    IN gctSTRING Destination,
-    IN gctSIZE_T DestinationSize,
-    IN gctCONST_STRING Source
-    )
-{
-    gctSIZE_T n;
-
-    gcmHEADER_ARG("Destination=0x%x DestinationSize=%lu Source=0x%x",
-                  Destination, DestinationSize, Source);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Destination != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Source != gcvNULL);
-
-    /* Find the end of the destination. */
-    n = strlen(Destination);
-    if (n + 1 < DestinationSize)
-    {
-        /* Append the string but don't overflow the destination buffer. */
-        strncpy(Destination + n, Source, DestinationSize - n - 1);
-
-        /* Put this there in case the strncpy overflows. */
-        Destination[DestinationSize - 1] = '\0';
-
-        /* Success. */
-        gcmFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-    else
-    {
-        /* Failure */
-        gcmFOOTER_ARG("%d", gcvSTATUS_TRUE);
-        return gcvSTATUS_TRUE;
-    }
-}
-
-/*******************************************************************************
-**
-**  gcoOS_StrCmp
-**
-**  Compare two strings and return whether they match or not.
-**
-**  INPUT:
-**
-**      gctCONST_STRING String1
-**          Pointer to the first string to compare.
-**
-**      gctCONST_STRING String2
-**          Pointer to the second string to compare.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**  RETURNS:
-**
-**      gcvSTATUS_OK if the strings match
-**      gcvSTATUS_LARGER if String1 > String2
-**      gcvSTATUS_SMALLER if String1 < String2
-*/
-gceSTATUS
-gcoOS_StrCmp(
-    IN gctCONST_STRING String1,
-    IN gctCONST_STRING String2
-    )
-{
-    int result;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("String1=0x%x String2=0x%x", String1, String2);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(String1 != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(String2 != gcvNULL);
-
-    /* Compare the strings and return proper status. */
-    result = strcmp(String1, String2);
-
-    status = (result == 0) ? gcvSTATUS_OK
-           : (result >  0) ? gcvSTATUS_LARGER
-                           : gcvSTATUS_SMALLER;
-
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_StrNCmp
-**
-**  Compare characters of two strings and return whether they match or not.
-**
-**  INPUT:
-**
-**      gctCONST_STRING String1
-**          Pointer to the first string to compare.
-**
-**      gctCONST_STRING String2
-**          Pointer to the second string to compare.
-**
-**      gctSIZE_T Count
-**          Number of characters to compare.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**  RETURNS:
-**
-**      gcvSTATUS_OK if the strings match
-**      gcvSTATUS_LARGER if String1 > String2
-**      gcvSTATUS_SMALLER if String1 < String2
-*/
-gceSTATUS
-gcoOS_StrNCmp(
-    IN gctCONST_STRING String1,
-    IN gctCONST_STRING String2,
-    IN gctSIZE_T Count
-    )
-{
-    int result;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("String1=0x%x String2=0x%x Count=%lu",
-                  String1, String2, Count);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(String1 != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(String2 != gcvNULL);
-
-    /* Compare the strings and return proper status. */
-    result = strncmp(String1, String2, Count);
-
-    status = (result == 0)
-            ? gcvSTATUS_OK
-            : ((result > 0) ? gcvSTATUS_LARGER : gcvSTATUS_SMALLER);
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_StrToFloat
-**
-**  Convert string to float.
-**
-**  INPUT:
-**
-**      gctCONST_STRING String
-**          Pointer to the string to be converted.
-**
-**
-**  OUTPUT:
-**
-**      gctFLOAT * Float
-**          Pointer to a variable that will receive the float.
-**
-*/
-gceSTATUS
-gcoOS_StrToFloat(
-    IN gctCONST_STRING String,
-    OUT gctFLOAT * Float
-    )
-{
-    gcmHEADER_ARG("String=%s", gcmOPT_STRING(String));
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(String != gcvNULL);
-
-    *Float = (gctFLOAT) atof(String);
-
-    gcmFOOTER_ARG("*Float=%f", *Float);
-    return gcvSTATUS_OK;
-}
-
-/* Converts a hex string to 32-bit integer. */
-gceSTATUS gcoOS_HexStrToInt(IN gctCONST_STRING String,
-               OUT gctINT * Int)
-{
-    gcmHEADER_ARG("String=%s", gcmOPT_STRING(String));
-    gcmDEBUG_VERIFY_ARGUMENT(String != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Int != gcvNULL);
-
-    sscanf(String, "%x", ((gctUINT*)Int));
-
-    gcmFOOTER_ARG("*Int=%d", *Int);
-    return gcvSTATUS_OK;
-}
-
-/* Converts a hex string to float. */
-gceSTATUS gcoOS_HexStrToFloat(IN gctCONST_STRING String,
-               OUT gctFLOAT * Float)
-{
-    gctSTRING pch = gcvNULL;
-    gctCONST_STRING delim = "x.p";
-    gctFLOAT b=0.0, exp=0.0;
-    gctINT s=0;
-    gctSTRING saveptr;
-
-    gcmHEADER_ARG("String=%s", gcmOPT_STRING(String));
-    gcmDEBUG_VERIFY_ARGUMENT(String != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Float != gcvNULL);
-
-    pch = strtok_r((gctSTRING)String, delim, &saveptr);
-    if (pch == NULL) goto onError;
-
-    pch = strtok_r(NULL, delim, &saveptr);
-    if (pch == NULL) goto onError;
-    gcmVERIFY_OK(gcoOS_StrToFloat(pch, &b));
-
-    pch = strtok_r(NULL, delim, &saveptr);
-    if (pch == NULL) goto onError;
-    gcmVERIFY_OK(gcoOS_HexStrToInt(pch, &s));
-
-    pch = strtok_r(NULL, delim, &saveptr);
-    if (pch == NULL) goto onError;
-    gcmVERIFY_OK(gcoOS_StrToFloat(pch, &exp));
-
-    *Float = (float)(b + s / (float)(1 << 24)) * (float)pow(2.0, exp);
-
-    gcmFOOTER_ARG("*Float=%d", *Float);
-    return gcvSTATUS_OK;
-
-onError:
-    gcmFOOTER_NO();
-    return gcvSTATUS_INVALID_ARGUMENT;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_StrToInt
-**
-**  Convert string to integer.
-**
-**  INPUT:
-**
-**      gctCONST_STRING String
-**          Pointer to the string to be converted.
-**
-**
-**  OUTPUT:
-**
-**      gctINT * Int
-**          Pointer to a variable that will receive the integer.
-**
-*/
-gceSTATUS
-gcoOS_StrToInt(
-    IN gctCONST_STRING String,
-    OUT gctINT * Int
-    )
-{
-    gcmHEADER_ARG("String=%s", gcmOPT_STRING(String));
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(String != gcvNULL);
-
-    *Int = (gctINT) atoi(String);
-
-    gcmFOOTER_ARG("*Int=%d", *Int);
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_MemCmp
-**
-**  Compare two memory regions and return whether they match or not.
-**
-**  INPUT:
-**
-**      gctCONST_POINTER Memory1
-**          Pointer to the first memory region to compare.
-**
-**      gctCONST_POINTER Memory2
-**          Pointer to the second memory region to compare.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes to compare.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**  RETURNS:
-**
-**      gcvSTATUS_OK if the memory regions match or gcvSTATUS_MISMATCH if the
-**      memory regions don't match.
-*/
-gceSTATUS
-gcoOS_MemCmp(
-    IN gctCONST_POINTER Memory1,
-    IN gctCONST_POINTER Memory2,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Memory1=0x%x Memory2=0x%x Bytes=%lu",
-                  Memory1, Memory2, Bytes);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Memory1 != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Memory2 != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Bytes > 0);
-
-    /* Compare the memory rregions and return proper status. */
-    status = (memcmp(Memory1, Memory2, Bytes) == 0)
-               ? gcvSTATUS_OK
-               : gcvSTATUS_MISMATCH;
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_PrintStr
-**
-**  Append a "printf" formatted string to a string buffer and adjust the offset
-**  into the string buffer.  There is no checking for a buffer overflow, so make
-**  sure the string buffer is large enough.
-**
-**  INPUT:
-**
-**      gctSTRING String
-**          Pointer to the string buffer.
-**
-**      gctUINT_PTR Offset
-**          Pointer to a variable that holds the current offset into the string
-**          buffer.
-**
-**      gctCONST_STRING Format
-**          Pointer to a "printf" style format to append to the string buffer
-**          pointet to by <String> at the offset specified by <*Offset>.
-**
-**      ...
-**          Variable number of arguments that will be used by <Format>.
-**
-**  OUTPUT:
-**
-**      gctUINT_PTR Offset
-**          Pointer to a variable that receives the new offset into the string
-**          buffer pointed to by <String> after the formatted string pointed to
-**          by <Formnat> has been appended to it.
-*/
-gceSTATUS
-gcoOS_PrintStrSafe(
-    IN gctSTRING String,
-    IN gctSIZE_T StringSize,
-    IN OUT gctUINT_PTR Offset,
-    IN gctCONST_STRING Format,
-    ...
-    )
-{
-    gctARGUMENTS arguments;
-    gceSTATUS status = gcvSTATUS_OK;
-
-    gcmHEADER_ARG("String=0x%x StringSize=%lu *Offset=%u Format=0x%x",
-                  String, StringSize, gcmOPT_VALUE(Offset), Format);
-
-    /* Verify the arguments. */
-    gcmVERIFY_ARGUMENT(String != gcvNULL);
-    gcmVERIFY_ARGUMENT(StringSize > 0);
-    gcmVERIFY_ARGUMENT(Format != gcvNULL);
-
-    /* Route through gcoOS_PrintStrVSafe. */
-    gcmARGUMENTS_START(arguments, Format);
-    gcmONERROR(gcoOS_PrintStrVSafe(String, StringSize,
-                                   Offset,
-                                   Format, arguments));
-
-OnError:
-    gcmARGUMENTS_END(arguments);
-
-    gcmFOOTER_ARG("*Offset=%u", gcmOPT_VALUE(Offset));
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_PrintStrV
-**
-**  Append a "vprintf" formatted string to a string buffer and adjust the offset
-**  into the string buffer.  There is no checking for a buffer overflow, so make
-**  sure the string buffer is large enough.
-**
-**  INPUT:
-**
-**      gctSTRING String
-**          Pointer to the string buffer.
-**
-**      gctUINT_PTR Offset
-**          Pointer to a variable that holds the current offset into the string
-**          buffer.
-**
-**      gctCONST_STRING Format
-**          Pointer to a "printf" style format to append to the string buffer
-**          pointet to by <String> at the offset specified by <*Offset>.
-**
-**      gctPOINTER ArgPtr
-**          Pointer to list of arguments.
-**
-**  OUTPUT:
-**
-**      gctUINT_PTR Offset
-**          Pointer to a variable that receives the new offset into the string
-**          buffer pointed to by <String> after the formatted string pointed to
-**          by <Formnat> has been appended to it.
-*/
-gceSTATUS
-gcoOS_PrintStrVSafe(
-    OUT gctSTRING String,
-    IN gctSIZE_T StringSize,
-    IN OUT gctUINT_PTR Offset,
-    IN gctCONST_STRING Format,
-    IN gctARGUMENTS Arguments
-    )
-{
-    gctUINT offset = gcmOPT_VALUE(Offset);
-    gceSTATUS status = gcvSTATUS_OK;
-
-    gcmHEADER_ARG("String=0x%x StringSize=%lu *Offset=%u Format=0x%x Arguments=0x%x",
-                  String, StringSize, offset, Format, Arguments);
-
-    /* Verify the arguments. */
-    gcmVERIFY_ARGUMENT(String != gcvNULL);
-    gcmVERIFY_ARGUMENT(StringSize > 0);
-    gcmVERIFY_ARGUMENT(Format != gcvNULL);
-
-    if (offset < StringSize - 1)
-    {
-        /* Print into the string. */
-        gctINT n = vsnprintf(String + offset,
-                             StringSize - offset,
-                             Format,
-                             Arguments);
-
-        if (n < 0 || n >= (gctINT)(StringSize - offset))
-        {
-            status = gcvSTATUS_GENERIC_IO;
-        }
-        else if (Offset)
-        {
-            *Offset = offset + n;
-        }
-    }
-    else
-    {
-        status = gcvSTATUS_BUFFER_TOO_SMALL;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*Offset=%u", offset);
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_StrDup
-**
-**  Duplicate the given string by copying it into newly allocated memory.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctCONST_STRING String
-**          Pointer to string to duplicate.
-**
-**  OUTPUT:
-**
-**      gctSTRING * Target
-**          Pointer to variable holding the duplicated string address.
-*/
-gceSTATUS
-gcoOS_StrDup(
-    IN gcoOS Os,
-    IN gctCONST_STRING String,
-    OUT gctSTRING * Target
-    )
-{
-    gctSIZE_T bytes;
-    gctSTRING string;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("String=0x%x", String);
-
-    gcmDEBUG_VERIFY_ARGUMENT(String != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Target != gcvNULL);
-
-    bytes = gcoOS_StrLen(String, gcvNULL);
-
-    gcmONERROR(gcoOS_Allocate(gcvNULL, bytes + 1, (gctPOINTER *) &string));
-
-    memcpy(string, String, bytes + 1);
-
-    *Target = string;
-
-    /* Success. */
-    gcmFOOTER_ARG("*Target=0x%x", gcmOPT_VALUE(Target));
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_LoadLibrary
-**
-**  Load a library.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctCONST_STRING Library
-**          Name of library to load.
-**
-**  OUTPUT:
-**
-**      gctHANDLE * Handle
-**          Pointer to variable receiving the library handle.
-*/
-
-gceSTATUS
-gcoOS_LoadLibrary(
-    IN gcoOS Os,
-    IN gctCONST_STRING Library,
-    OUT gctHANDLE * Handle
-    )
-{
-#if gcdSTATIC_LINK
-    return gcvSTATUS_NOT_SUPPORTED;
-#else
-    gctSIZE_T length;
-    gctSTRING library = gcvNULL;
-    gceSTATUS status = gcvSTATUS_OK;
-
-    gcmHEADER_ARG("Library=%s", gcmOPT_STRING(Library));
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Handle != gcvNULL);
-
-    /* Reset the handle. */
-    *Handle = gcvNULL;
-
-    if (Library != gcvNULL)
-    {
-        /* Get the length of the library name. */
-        length = strlen(Library);
-
-        /* Test if the libray has ".so" at the end. */
-        if (strcmp(Library + length - 3, ".so") != 0)
-        {
-            /* Allocate temporay string buffer. */
-            gcmONERROR(gcoOS_Allocate(
-                gcvNULL, length + 4 + 1, (gctPOINTER *) &library
-                ));
-
-            /* Copy the library name to the temporary string buffer. */
-            strcpy(library, Library);
-
-            /* Append the ".so" to the temporary string buffer. */
-            strcat(library, ".so");
-
-            /* Replace the library name. */
-            Library = library;
-        }
-
-        *Handle = dlopen(Library, RTLD_NOW);
-
-        /* Failed? */
-        if (*Handle == gcvNULL)
-        {
-            gcmTRACE(
-                gcvLEVEL_VERBOSE, "%s(%d): %s", __FUNCTION__, __LINE__, dlerror()
-                );
-
-            /* Library could not be loaded. */
-            status = gcvSTATUS_NOT_FOUND;
-        }
-    }
-
-OnError:
-    /* Free the temporary string buffer. */
-    if (library != gcvNULL)
-    {
-        gcmVERIFY_OK(gcmOS_SAFE_FREE(gcvNULL, library));
-    }
-
-    gcmFOOTER_ARG("*Handle=0x%x status=%d", *Handle, status);
-    return status;
-#endif
-}
-
-/*******************************************************************************
-**
-**  gcoOS_FreeLibrary
-**
-**  Unload a loaded library.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctHANDLE Handle
-**          Handle of a loaded libarry.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_FreeLibrary(
-    IN gcoOS Os,
-    IN gctHANDLE Handle
-    )
-{
-#if gcdSTATIC_LINK
-    return gcvSTATUS_NOT_SUPPORTED;
-#else
-    gcmHEADER_ARG("Handle=0x%x", Handle);
-
-#if !gcdBUILT_FOR_VALGRIND
-    /* Free the library. */
-    dlclose(Handle);
-#endif
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-#endif
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetProcAddress
-**
-**  Get the address of a function inside a loaded library.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctHANDLE Handle
-**          Handle of a loaded libarry.
-**
-**      gctCONST_STRING Name
-**          Name of function to get the address of.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * Function
-**          Pointer to variable receiving the function pointer.
-*/
-gceSTATUS
-gcoOS_GetProcAddress(
-    IN gcoOS Os,
-    IN gctHANDLE Handle,
-    IN gctCONST_STRING Name,
-    OUT gctPOINTER * Function
-    )
-{
-#if gcdSTATIC_LINK
-    return gcvSTATUS_NOT_SUPPORTED;
-#else
-    gceSTATUS status = gcvSTATUS_OK;
-
-    gcmHEADER_ARG("Handle=0x%x Name=%s", Handle, gcmOPT_STRING(Name));
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Name != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Function != gcvNULL);
-
-    /* Get the address of the function. */
-    *Function = dlsym(Handle, Name);
-
-    if (*Function == gcvNULL)
-    {
-        gcmTRACE(
-            gcvLEVEL_WARNING,
-            "%s(%d): Function %s not found.",
-            __FUNCTION__, __LINE__, Name
-            );
-
-        /* Function could not be found. */
-        status = gcvSTATUS_NOT_FOUND;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*Function=0x%x status=%d", *Function, status);
-    return status;
-#endif
-}
-
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-gceSTATUS
-gcoOS_ProfileStart(
-    IN gcoOS Os
-    )
-{
-    gcPLS.os->allocCount   = 0;
-    gcPLS.os->allocSize    = 0;
-    gcPLS.os->maxAllocSize = 0;
-    gcPLS.os->freeCount    = 0;
-    gcPLS.os->freeSize     = 0;
-
-#if gcdGC355_MEM_PRINT
-    gcPLS.os->oneRecording = 0;
-    gcPLS.os->oneSize      = 0;
-#endif
-
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gcoOS_ProfileEnd(
-    IN gcoOS Os,
-    IN gctCONST_STRING Title
-    )
-{
-    gcmPRINT("10) System memory - current: %u \n", gcPLS.os->allocSize);
-    gcmPRINT("11) System memory - maximum: %u \n", gcPLS.os->maxAllocSize);
-    gcmPRINT("12) System memory - total: %u \n", (gcPLS.os->allocSize + gcPLS.os->freeSize));
-    gcmPRINT("13) System memory - allocation count: %u \n", gcPLS.os->allocCount);
-    gcmPRINT("14) System memory - deallocation count: %u \n", gcPLS.os->freeCount);
-
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_SetProfileSetting
-**
-**  Set Vivante profiler settings.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctBOOL Enable
-**          Enable or Disable Vivante profiler.
-**
-**      gctCONST_STRING FileName
-**          Specify FileName for storing profile data into.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_SetProfileSetting(
-    IN gcoOS Os,
-    IN gctBOOL Enable,
-    IN gctCONST_STRING FileName
-    )
-{
-    gcsHAL_INTERFACE iface;
-
-    if (strlen(FileName) >= gcdMAX_PROFILE_FILE_NAME)
-    {
-        return gcvSTATUS_INVALID_ARGUMENT;
-    }
-
-    /* Initialize the gcsHAL_INTERFACE structure. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_SET_PROFILE_SETTING;
-    iface.u.SetProfileSetting.enable = Enable;
-
-    /* Call the kernel. */
-    return gcoOS_DeviceControl(gcvNULL,
-                               IOCTL_GCHAL_INTERFACE,
-                               &iface, gcmSIZEOF(iface),
-                               &iface, gcmSIZEOF(iface));
-}
-#endif
-
-gceSTATUS
-gcoOS_Compact(
-    IN gcoOS Os
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/*----------------------------------------------------------------------------*/
-/*----------------------------------- Atoms ----------------------------------*/
-/* Create an atom. */
-gceSTATUS
-gcoOS_AtomConstruct(
-    IN gcoOS Os,
-    OUT gcsATOM_PTR * Atom
-    )
-{
-    gceSTATUS status;
-    gcsATOM_PTR atom = gcvNULL;
-
-    gcmHEADER();
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Atom != gcvNULL);
-
-    do
-    {
-        /* Allocate memory for the atom. */
-        gcmERR_BREAK(gcoOS_Allocate(gcvNULL,
-                                    gcmSIZEOF(struct gcsATOM),
-                                    (gctPOINTER *) &atom));
-
-        /* Initialize the atom to 0. */
-        atom->counter = 0;
-
-#if !gcdBUILTIN_ATOMIC_FUNCTIONS
-        if (pthread_mutex_init(&atom->mutex, gcvNULL) != 0)
-        {
-            status = gcvSTATUS_OUT_OF_RESOURCES;
-            break;
-        }
-#endif
-
-        /* Return pointer to atom. */
-        *Atom = atom;
-
-        /* Success. */
-        gcmFOOTER_ARG("*Atom=%p", *Atom);
-        return gcvSTATUS_OK;
-    }
-    while (gcvFALSE);
-
-    /* Free the atom. */
-    if (atom != gcvNULL)
-    {
-        gcmOS_SAFE_FREE(gcvNULL, atom);
-    }
-
-    /* Return error status. */
-    gcmFOOTER();
-    return status;
-}
-
-/* Destroy an atom. */
-gceSTATUS
-gcoOS_AtomDestroy(
-    IN gcoOS Os,
-    IN gcsATOM_PTR Atom
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Atom=0x%x", Atom);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Atom != gcvNULL);
-
-    /* Free the atom. */
-    status = gcmOS_SAFE_FREE(gcvNULL, Atom);
-
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-gceSTATUS
-gcoOS_AtomGet(
-    IN gcoOS Os,
-    IN gcsATOM_PTR Atom,
-    OUT gctINT32_PTR Value
-    )
-{
-    gcmHEADER_ARG("Atom=0x%0x", Atom);
-
-    /* Verify the arguments. */
-    gcmVERIFY_ARGUMENT(Atom != gcvNULL);
-
-    /* Get the atom value. */
-    *Value = Atom->counter;
-
-    /* Success. */
-    gcmFOOTER_ARG("*Value=%d", *Value);
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gcoOS_AtomSet(
-    IN gcoOS Os,
-    IN gcsATOM_PTR Atom,
-    IN gctINT32 Value
-    )
-{
-    gcmHEADER_ARG("Atom=0x%0x Value=%d", Atom, Value);
-
-    /* Verify the arguments. */
-    gcmVERIFY_ARGUMENT(Atom != gcvNULL);
-
-    /* Set the atom value. */
-    Atom->counter = Value;
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/* Increment an atom. */
-gceSTATUS
-gcoOS_AtomIncrement(
-    IN gcoOS Os,
-    IN gcsATOM_PTR Atom,
-    OUT gctINT32_PTR OldValue OPTIONAL
-    )
-{
-    gctINT32 value;
-
-    gcmHEADER_ARG("Atom=0x%x", Atom);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Atom != gcvNULL);
-
-    /* Increment the atom's counter. */
-#if gcdBUILTIN_ATOMIC_FUNCTIONS
-    value = __sync_fetch_and_add(&Atom->counter, 1);
-#else
-    /* Lock the mutex. */
-    pthread_mutex_lock(&Atom->mutex);
-
-    /* Get original value. */
-    value = Atom->counter;
-
-    /* Add given value. */
-    Atom->counter += 1;
-
-    /* Unlock the mutex. */
-    pthread_mutex_unlock(&Atom->mutex);
-#endif
-
-    if (OldValue != gcvNULL)
-    {
-        /* Return the original value to the caller. */
-        *OldValue = value;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*OldValue=%d", gcmOPT_VALUE(OldValue));
-    return gcvSTATUS_OK;
-}
-
-/* Decrement an atom. */
-gceSTATUS
-gcoOS_AtomDecrement(
-    IN gcoOS Os,
-    IN gcsATOM_PTR Atom,
-    OUT gctINT32_PTR OldValue OPTIONAL
-    )
-{
-    gctINT32 value;
-
-    gcmHEADER_ARG("Atom=0x%x", Atom);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Atom != gcvNULL);
-
-    /* Decrement the atom's counter. */
-#if gcdBUILTIN_ATOMIC_FUNCTIONS
-    value = __sync_fetch_and_sub(&Atom->counter, 1);
-#else
-    /* Lock the mutex. */
-    pthread_mutex_lock(&Atom->mutex);
-
-    /* Get original value. */
-    value = Atom->counter;
-
-    /* Subtract given value. */
-    Atom->counter -= 1;
-
-    /* Unlock the mutex. */
-    pthread_mutex_unlock(&Atom->mutex);
-#endif
-
-    if (OldValue != gcvNULL)
-    {
-        /* Return the original value to the caller. */
-        *OldValue = value;
-    }
-
-    /* Success. */
-    gcmFOOTER_ARG("*OldValue=%d", gcmOPT_VALUE(OldValue));
-    return gcvSTATUS_OK;
-}
-
-gctHANDLE
-gcoOS_GetCurrentProcessID(
-    void
-    )
-{
-    return (gctHANDLE)(gctUINTPTR_T) taskIdSelf();
-}
-
-gctHANDLE
-gcoOS_GetCurrentThreadID(
-    void
-    )
-{
-    return (gctHANDLE) pthread_self();
-}
-
-/*----------------------------------------------------------------------------*/
-/*----------------------------------- Time -----------------------------------*/
-
-/*******************************************************************************
-**
-**  gcoOS_GetTicks
-**
-*/
-gctUINT32
-gcoOS_GetTicks(
-    void
-    )
-{
-    /* TODO; */
-    return 0;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetTime
-**
-**  Get the number of ueconds since 1970/1/1.
-**
-**  INPUT:
-**
-**  OUTPUT:
-**
-**      gctUINT64_PTR Time
-**          Pointer to a variable to get time.
-**
-*/
-gceSTATUS
-gcoOS_GetTime(
-    OUT gctUINT64_PTR Time
-    )
-{
-    struct timespec tv;
-
-    clock_gettime(CLOCK_REALTIME, &tv);
-
-    *Time = (tv.tv_sec * 1000000) + (tv.tv_nsec + 500 / 1000);
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetCPUTime
-**
-**  Get CPU time usage in microseconds.
-**
-**  INPUT:
-**
-**  OUTPUT:
-**
-**      gctUINT64_PTR CPUTime
-**          Pointer to a variable to get CPU time usage.
-**
-*/
-gceSTATUS
-gcoOS_GetCPUTime(
-    OUT gctUINT64_PTR CPUTime
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_GetMemoryUsage
-**
-**  Get current processes resource usage.
-**
-**  INPUT:
-**
-**  OUTPUT:
-**
-**      gctUINT32_PTR MaxRSS
-**          Total amount of resident set memory used.
-**          The value will be in terms of memory pages used.
-**
-**      gctUINT32_PTR IxRSS
-**          Total amount of memory used by the text segment
-**          in kilobytes multiplied by the execution-ticks.
-**
-**      gctUINT32_PTR IdRSS
-**          Total amount of private memory used by a process
-**          in kilobytes multiplied by execution-ticks.
-**
-**      gctUINT32_PTR IsRSS
-**          Total amount of memory used by the stack in
-**          kilobytes multiplied by execution-ticks.
-**
-*/
-gceSTATUS
-gcoOS_GetMemoryUsage(
-    OUT gctUINT32_PTR MaxRSS,
-    OUT gctUINT32_PTR IxRSS,
-    OUT gctUINT32_PTR IdRSS,
-    OUT gctUINT32_PTR IsRSS
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_ReadRegister
-**
-**  Read data from a register.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctUINT32 Address
-**          Address of register.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Data
-**          Pointer to a variable that receives the data read from the register.
-*/
-gceSTATUS
-gcoOS_ReadRegister(
-    IN gcoOS Os,
-    IN gctUINT32 Address,
-    OUT gctUINT32 * Data
-    )
-{
-    gcsHAL_INTERFACE iface;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Address=0x%x", Address);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Data != gcvNULL);
-
-    /* Initialize the gcsHAL_INTERFACE structure. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_READ_REGISTER;
-    iface.u.ReadRegisterData.address = Address;
-    iface.u.ReadRegisterData.data    = 0xDEADDEAD;
-
-    /* Call kernel driver. */
-    gcmONERROR(gcoOS_DeviceControl(gcvNULL,
-                                   IOCTL_GCHAL_INTERFACE,
-                                   &iface, gcmSIZEOF(iface),
-                                   &iface, gcmSIZEOF(iface)));
-
-    /* Return the Data on success. */
-    *Data = iface.u.ReadRegisterData.data;
-
-    /* Success. */
-    gcmFOOTER_ARG("*Data=0x%08x", *Data);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_WriteRegister
-**
-**  Write data to a register.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctUINT32 Address
-**          Address of register.
-**
-**      gctUINT32 Data
-**          Data for register.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_WriteRegister(
-    IN gcoOS Os,
-    IN gctUINT32 Address,
-    IN gctUINT32 Data
-    )
-{
-    gcsHAL_INTERFACE iface;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Address=0x%x Data=0x%08x", Address, Data);
-
-    /* Initialize the gcsHAL_INTERFACE structure. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_WRITE_REGISTER;
-    iface.u.WriteRegisterData.address = Address;
-    iface.u.WriteRegisterData.data    = Data;
-
-    /* Call kernel driver. */
-    gcmONERROR(gcoOS_DeviceControl(gcvNULL,
-                                   IOCTL_GCHAL_INTERFACE,
-                                   &iface, gcmSIZEOF(iface),
-                                   &iface, gcmSIZEOF(iface)));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-static gceSTATUS
-gcoOS_Cache(
-    IN gctUINT32 Node,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes,
-    IN gceCACHEOPERATION Operation
-    )
-{
-    gcsHAL_INTERFACE ioctl;
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Node=0x%x Logical=0x%x Bytes=%u Operation=%d",
-                  Node, Logical, Bytes, Operation);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(Bytes > 0);
-
-    /* Set up the cache. */
-    ioctl.ignoreTLS          = gcvFALSE;
-    ioctl.command            = gcvHAL_CACHE;
-    ioctl.u.Cache.operation  = Operation;
-    ioctl.u.Cache.node       = Node;
-    ioctl.u.Cache.logical    = gcmPTR_TO_UINT64(Logical);
-    ioctl.u.Cache.bytes      = Bytes;
-
-    /* Call the kernel. */
-    gcmONERROR(gcoOS_DeviceControl(gcvNULL,
-                                   IOCTL_GCHAL_INTERFACE,
-                                   &ioctl, gcmSIZEOF(ioctl),
-                                   &ioctl, gcmSIZEOF(ioctl)));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**  gcoOS_CacheClean
-**
-**  Clean the cache for the specified addresses.  The GPU is going to need the
-**  data.  If the system is allocating memory as non-cachable, this function can
-**  be ignored.
-**
-**  ARGUMENTS:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctUINT32 Node
-**          Pointer to the video memory node that needs to be flushed.
-**
-**      gctPOINTER Logical
-**          Logical address to flush.
-**
-**      gctSIZE_T Bytes
-**          Size of the address range in bytes to flush.
-*/
-gceSTATUS
-gcoOS_CacheClean(
-    IN gcoOS Os,
-    IN gctUINT32 Node,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Node=0x%x Logical=0x%x Bytes=%u",
-                  Node, Logical, Bytes);
-
-    /* Call common code. */
-    gcmONERROR(gcoOS_Cache(Node, Logical, Bytes, gcvCACHE_CLEAN));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**  gcoOS_CacheFlush
-**
-**  Flush the cache for the specified addresses and invalidate the lines as
-**  well.  The GPU is going to need and modify the data.  If the system is
-**  allocating memory as non-cachable, this function can be ignored.
-**
-**  ARGUMENTS:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctUINT32 Node
-**          Pointer to the video memory node that needs to be flushed.
-**
-**      gctPOINTER Logical
-**          Logical address to flush.
-**
-**      gctSIZE_T Bytes
-**          Size of the address range in bytes to flush.
-*/
-gceSTATUS
-gcoOS_CacheFlush(
-    IN gcoOS Os,
-    IN gctUINT32 Node,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Node=0x%x Logical=0x%x Bytes=%u",
-                  Node, Logical, Bytes);
-
-    /* Call common code. */
-    gcmONERROR(gcoOS_Cache(Node, Logical, Bytes, gcvCACHE_FLUSH));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**  gcoOS_CacheInvalidate
-**
-**  Invalidate the lines. The GPU is going modify the data.  If the system is
-**  allocating memory as non-cachable, this function can be ignored.
-**
-**  ARGUMENTS:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctUINT32 Node
-**          Pointer to the video memory node that needs to be invalidated.
-**
-**      gctPOINTER Logical
-**          Logical address to flush.
-**
-**      gctSIZE_T Bytes
-**          Size of the address range in bytes to invalidated.
-*/
-gceSTATUS
-gcoOS_CacheInvalidate(
-    IN gcoOS Os,
-    IN gctUINT32 Node,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Node=0x%x Logical=0x%x Bytes=%u",
-                  Node, Logical, Bytes);
-
-    /* Call common code. */
-    gcmONERROR(gcoOS_Cache(Node, Logical, Bytes, gcvCACHE_INVALIDATE));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**  gcoOS_MemoryBarrier
-**  Make sure the CPU has executed everything up to this point and the data got
-**  written to the specified pointer.
-**  ARGUMENTS:
-**
-**      gcoOS Os
-**          Pointer to gcoOS object.
-**
-**      gctPOINTER Logical
-**          Logical address to flush.
-**
-*/
-gceSTATUS
-gcoOS_MemoryBarrier(
-    IN gcoOS Os,
-    IN gctPOINTER Logical
-    )
-{
-    gceSTATUS status;
-
-    gcmHEADER_ARG("Logical=0x%x", Logical);
-
-    /* Call common code. */
-    gcmONERROR(gcoOS_Cache(0, Logical, 1, gcvCACHE_MEMORY_BARRIER));
-
-    /* Success. */
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmFOOTER();
-    return status;
-}
-
-
-/*----------------------------------------------------------------------------*/
-/*----- Profiling ------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-
-#if gcdENABLE_PROFILING
-gceSTATUS
-gcoOS_GetProfileTick(
-    OUT gctUINT64_PTR Tick
-    )
-{
-#ifdef CLOCK_MONOTONIC
-    struct timespec time;
-
-    clock_gettime(CLOCK_MONOTONIC, &time);
-
-    *Tick = time.tv_nsec + time.tv_sec * 1000000000ULL;
-
-    return gcvSTATUS_OK;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
-}
-
-gceSTATUS
-gcoOS_QueryProfileTickRate(
-    OUT gctUINT64_PTR TickRate
-    )
-{
-#ifdef CLOCK_MONOTONIC
-    struct timespec res;
-
-    clock_getres(CLOCK_MONOTONIC, &res);
-
-    *TickRate = res.tv_nsec + res.tv_sec * 1000000000ULL;
-
-    return gcvSTATUS_OK;
-#else
-    return gcvSTATUS_NOT_SUPPORTED;
-#endif
-}
-
-/*******************************************************************************
-**  gcoOS_ProfileDB
-**
-**  Manage the profile database.
-**
-**  The database layout is very simple:
-**
-**      <RecordID> (1 byte) <record data>
-**
-**  The <RecordID> can be one of the following values:
-**
-**      1       Initialize a new function to be profiled. Followed by the NULL-
-**              terminated name of the function, 4 bytes of the function ID and
-**              8 bytes of the profile tick.
-**      2       Enter a function to be profiled. Followed by 4 bytes of function
-**              ID and 8 bytes of the profile tick.
-**      3       Exit a function to be profiled. Followed by 8 bytes of the
-**              profile tick.
-**
-**  There are three options to manage the profile database. One would be to
-**  enter a function that needs to be profiled. This is specified with both
-**  <Function> and <Initialized> pointers initialized to some value. Here
-**  <Function> is pointing to a string with the function name and <Initialized>
-**  is pointing to a boolean value that tells the profiler whether this function
-**  has been initialized or not.
-**
-**  The second option would be to exit a function that was being profiled. This
-**  is specified by <Function> pointing to a string with the function name and
-**  <Initialized> set to gcvNULL.
-**
-**  The third and last option is to flush the profile database. This is
-**  specified with <Function> set to gcvNULL.
-**
-***** PARAMETERS
-**
-**  Function
-**
-**      Pointer to a string with the function name being profiled or gcvNULL to
-**      flush the profile database.
-**
-**  Initialized
-**
-**      Pointer to a boolean variable that informs the profiler if the entry of
-**      a function has been initialized or not, or gcvNULL to mark the exit of a
-**      function being profiled.
-*/
-void
-gcoOS_ProfileDB(
-    IN gctCONST_STRING Function,
-    IN OUT gctBOOL_PTR Initialized
-    )
-{
-    gctUINT64 nanos;
-    static gctUINT8_PTR profileBuffer = gcvNULL;
-    static gctSIZE_T profileSize, profileThreshold, totalBytes;
-    static gctUINT32 profileIndex;
-    static gctINT profileLevel;
-    static FILE * profileDB = gcvNULL;
-    int len, bytes;
-
-    /* Check if we need to flush the profile database. */
-    if (Function == gcvNULL)
-    {
-        if (profileBuffer != gcvNULL)
-        {
-            /* Check of the profile database exists. */
-            if (profileIndex > 0)
-            {
-                if (profileDB == gcvNULL)
-                {
-                    /* Open the profile database file. */
-                    profileDB = fopen("profile.database", "wb");
-                }
-
-                if (profileDB != gcvNULL)
-                {
-                    /* Write the profile database to the file. */
-                    totalBytes += fwrite(profileBuffer,
-                                         1, profileIndex,
-                                         profileDB);
-                }
-            }
-
-            if (profileDB != gcvNULL)
-            {
-                /* Convert the size of the profile database into a nice human
-                ** readable format. */
-                char buf[] = "#,###,###,###";
-                int i;
-
-                i = strlen(buf);
-                while ((totalBytes != 0) && (i > 0))
-                {
-                    if (buf[--i] == ',') --i;
-
-                    buf[i]      = '0' + (totalBytes % 10);
-                    totalBytes /= 10;
-                }
-
-                /* Print the size of the profile database. */
-                gcmPRINT("Closing the profile database: %s bytes.", &buf[i]);
-
-                /* Close the profile database file. */
-                fclose(profileDB);
-                profileDB = gcvNULL;
-            }
-
-            /* Destroy the profile database. */
-            free(profileBuffer);
-            profileBuffer = gcvNULL;
-        }
-    }
-
-    /* Check if we have to enter a function. */
-    else if (Initialized != gcvNULL)
-    {
-        /* Check if the profile database exists or not. */
-        if (profileBuffer == gcvNULL)
-        {
-            /* Allocate the profile database. */
-            for (profileSize = 32 << 20;
-                 profileSize > 0;
-                 profileSize -= 1 << 20
-            )
-            {
-                profileBuffer = malloc(profileSize);
-
-                if (profileBuffer != gcvNULL)
-                {
-                    break;
-                }
-            }
-
-            if (profileBuffer == gcvNULL)
-            {
-                /* Sorry - no memory. */
-                gcmPRINT("Cannot create the profile buffer!");
-                return;
-            }
-
-            /* Reset the profile database. */
-            profileThreshold = gcmMIN(profileSize / 2, 4 << 20);
-            totalBytes       = 0;
-            profileIndex     = 0;
-            profileLevel     = 0;
-        }
-
-        /* Increment the profile level. */
-        ++profileLevel;
-
-        /* Determine number of bytes to copy. */
-        len   = strlen(Function) + 1;
-        bytes = 1 + (*Initialized ? 0 : len) + 4 + 8;
-
-        /* Check if the profile database has enough space. */
-        if (profileIndex + bytes > profileSize)
-        {
-            gcmPRINT("PROFILE ENTRY: index=%lu size=%lu bytes=%d level=%d",
-                     profileIndex, profileSize, bytes, profileLevel);
-
-            if (profileDB == gcvNULL)
-            {
-                /* Open the profile database file. */
-                profileDB = fopen("profile.database", "wb");
-            }
-
-            if (profileDB != gcvNULL)
-            {
-                /* Write the profile database to the file. */
-                totalBytes += fwrite(profileBuffer, 1, profileIndex, profileDB);
-            }
-
-            /* Empty the profile databse. */
-            profileIndex = 0;
-        }
-
-        /* Check whether this function is initialized or not. */
-        if (*Initialized)
-        {
-            /* Already initialized - don't need to save name. */
-            profileBuffer[profileIndex] = 2;
-        }
-        else
-        {
-            /* Not yet initialized, save name as well. */
-            profileBuffer[profileIndex] = 1;
-            memcpy(profileBuffer + profileIndex + 1, Function, len);
-            profileIndex += len;
-
-            /* Mark function as initialized. */
-            *Initialized = gcvTRUE;
-        }
-
-        /* Copy the function ID into the profile database. */
-        memcpy(profileBuffer + profileIndex + 1, &Initialized, 4);
-
-        /* Get the profile tick. */
-        gcoOS_GetProfileTick(&nanos);
-
-        /* Copy the profile tick into the profile database. */
-        memcpy(profileBuffer + profileIndex + 5, &nanos, 8);
-        profileIndex += 1 + 4 + 8;
-    }
-
-    /* Exit a function, check whether the profile database is around. */
-    else if (profileBuffer != gcvNULL)
-    {
-        /* Get the profile tick. */
-        gcoOS_GetProfileTick(&nanos);
-
-        /* Check if the profile database has enough space. */
-        if (profileIndex + 1 + 8 > profileSize)
-        {
-            gcmPRINT("PROFILE EXIT: index=%lu size=%lu bytes=%d level=%d",
-                     profileIndex, profileSize, 1 + 8, profileLevel);
-
-            if (profileDB == gcvNULL)
-            {
-                /* Open the profile database file. */
-                profileDB = fopen("profile.database", "wb");
-            }
-
-            if (profileDB != gcvNULL)
-            {
-                /* Write the profile database to the file. */
-                totalBytes += fwrite(profileBuffer, 1, profileIndex, profileDB);
-            }
-
-            /* Empty the profile databse. */
-            profileIndex = 0;
-        }
-
-        /* Copy the profile tick into the profile database. */
-        profileBuffer[profileIndex] = 3;
-        memcpy(profileBuffer + profileIndex + 1, &nanos, 8);
-        profileIndex += 1 + 8;
-
-        /* Decrease the profile level and check whether the profile database is
-        ** getting too big if we exit a top-level function. */
-        if ((--profileLevel == 0)
-        &&  (profileSize - profileIndex < profileThreshold)
-        )
-        {
-            if (profileDB == gcvNULL)
-            {
-                /* Open the profile database file. */
-                profileDB = fopen("profile.database", "wb");
-            }
-
-            if (profileDB != gcvNULL)
-            {
-                /* Write the profile database to the file. */
-                totalBytes += fwrite(profileBuffer, 1, profileIndex, profileDB);
-
-                /* Flush the file now. */
-                fflush(profileDB);
-            }
-
-            /* Empty the profile databse. */
-            profileIndex = 0;
-        }
-    }
-}
-#endif
-
-/******************************************************************************\
-******************************* Signal Management ******************************
-\******************************************************************************/
-
-#undef _GC_OBJ_ZONE
-#define _GC_OBJ_ZONE    gcvZONE_SIGNAL
-
-/*******************************************************************************
-**
-**  gcoOS_CreateSignal
-**
-**  Create a new signal.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctBOOL ManualReset
-**          If set to gcvTRUE, gcoOS_Signal with gcvFALSE must be called in
-**          order to set the signal to nonsignaled state.
-**          If set to gcvFALSE, the signal will automatically be set to
-**          nonsignaled state by gcoOS_WaitSignal function.
-**
-**  OUTPUT:
-**
-**      gctSIGNAL * Signal
-**          Pointer to a variable receiving the created gctSIGNAL.
-*/
-gceSTATUS
-gcoOS_CreateSignal(
-    IN gcoOS Os,
-    IN gctBOOL ManualReset,
-    OUT gctSIGNAL * Signal
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("ManualReset=%d", ManualReset);
-
-    /* Verify the arguments. */
-    gcmDEBUG_VERIFY_ARGUMENT(Signal != gcvNULL);
-
-    /* Initialize the gcsHAL_INTERFACE structure. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_USER_SIGNAL;
-    iface.u.UserSignal.command     = gcvUSER_SIGNAL_CREATE;
-    iface.u.UserSignal.manualReset = ManualReset;
-
-    /* Call kernel driver. */
-    gcmONERROR(gcoOS_DeviceControl(gcvNULL,
-                                   IOCTL_GCHAL_INTERFACE,
-                                   &iface, gcmSIZEOF(iface),
-                                   &iface, gcmSIZEOF(iface)));
-
-    *Signal = (gctSIGNAL)(gctUINTPTR_T) iface.u.UserSignal.id;
-
-    gcmFOOTER_ARG("*Signal=0x%x", *Signal);
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_DestroySignal
-**
-**  Destroy a signal.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctSIGNAL Signal
-**          Pointer to the gctSIGNAL.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_DestroySignal(
-    IN gcoOS Os,
-    IN gctSIGNAL Signal
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("Signal=0x%x", Signal);
-
-    gcmTRACE_ZONE(
-        gcvLEVEL_VERBOSE, gcvZONE_OS,
-        "gcoOS_DestroySignal: signal->%d.",
-        (gctINT)(gctUINTPTR_T)Signal
-        );
-
-    /* Initialize the gcsHAL_INTERFACE structure. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_USER_SIGNAL;
-    iface.u.UserSignal.command = gcvUSER_SIGNAL_DESTROY;
-    iface.u.UserSignal.id      = (gctINT)(gctUINTPTR_T) Signal;
-
-    /* Call kernel driver. */
-    status = gcoOS_DeviceControl(gcvNULL,
-                                 IOCTL_GCHAL_INTERFACE,
-                                 &iface, gcmSIZEOF(iface),
-                                 &iface, gcmSIZEOF(iface));
-
-    /* Success. */
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_Signal
-**
-**  Set a state of the specified signal.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctSIGNAL Signal
-**          Pointer to the gctSIGNAL.
-**
-**      gctBOOL State
-**          If gcvTRUE, the signal will be set to signaled state.
-**          If gcvFALSE, the signal will be set to nonsignaled state.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_Signal(
-    IN gcoOS Os,
-    IN gctSIGNAL Signal,
-    IN gctBOOL State
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("Signal=0x%x State=%d", Signal, State);
-
-    /* Initialize the gcsHAL_INTERFACE structure. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_USER_SIGNAL;
-    iface.u.UserSignal.command = gcvUSER_SIGNAL_SIGNAL;
-    iface.u.UserSignal.id      = (gctINT)(gctUINTPTR_T) Signal;
-    iface.u.UserSignal.state   = State;
-
-    /* Call kernel driver. */
-    status = gcoOS_DeviceControl(gcvNULL,
-                                 IOCTL_GCHAL_INTERFACE,
-                                 &iface, gcmSIZEOF(iface),
-                                 &iface, gcmSIZEOF(iface));
-
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_WaitSignal
-**
-**  Wait for a signal to become signaled.
-**
-**  INPUT:
-**
-**      gcoOS Os
-**          Pointer to an gcoOS object.
-**
-**      gctSIGNAL Signal
-**          Pointer to the gctSIGNAL.
-**
-**      gctUINT32 Wait
-**          Number of milliseconds to wait.
-**          Pass the value of gcvINFINITE for an infinite wait.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_WaitSignal(
-    IN gcoOS Os,
-    IN gctSIGNAL Signal,
-    IN gctUINT32 Wait
-    )
-{
-#if gcdNULL_DRIVER
-    return gcvSTATUS_OK;
-#else
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("Signal=0x%x Wait=%u", Signal, Wait);
-
-    /* Initialize the gcsHAL_INTERFACE structure. */
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_USER_SIGNAL;
-    iface.u.UserSignal.command = gcvUSER_SIGNAL_WAIT;
-    iface.u.UserSignal.id      = (gctINT)(gctUINTPTR_T) Signal;
-    iface.u.UserSignal.wait    = Wait;
-
-    /* Call kernel driver. */
-    status = gcoOS_DeviceControl(gcvNULL,
-                                 IOCTL_GCHAL_INTERFACE,
-                                 &iface, gcmSIZEOF(iface),
-                                 &iface, gcmSIZEOF(iface));
-
-    gcmFOOTER_ARG("Signal=0x%x status=%d", Signal, status);
-    return status;
-#endif
-}
-
-/*******************************************************************************
-**
-**  gcoOS_MapSignal
-**
-**  Map a signal from another process.
-**
-**  INPUT:
-**
-**      gctSIGNAL  RemoteSignal
-**
-**  OUTPUT:
-**
-**      gctSIGNAL * LocalSignal
-**          Pointer to a variable receiving the created gctSIGNAL.
-*/
-gceSTATUS
-gcoOS_MapSignal(
-    IN gctSIGNAL  RemoteSignal,
-    OUT gctSIGNAL * LocalSignal
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("RemoteSignal=%d", RemoteSignal);
-
-    gcmDEBUG_VERIFY_ARGUMENT(RemoteSignal != gcvNULL);
-    gcmDEBUG_VERIFY_ARGUMENT(LocalSignal != gcvNULL);
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_USER_SIGNAL;
-    iface.u.UserSignal.command  = gcvUSER_SIGNAL_MAP;
-    iface.u.UserSignal.id = (gctINT)(gctUINTPTR_T) RemoteSignal;
-
-    gcmONERROR(gcoOS_DeviceControl(gcvNULL,
-                                   IOCTL_GCHAL_INTERFACE,
-                                   &iface, gcmSIZEOF(iface),
-                                   &iface, gcmSIZEOF(iface)));
-
-    *LocalSignal = (gctSIGNAL)(gctUINTPTR_T) iface.u.UserSignal.id;
-
-    gcmFOOTER_ARG("*LocalSignal=0x%x", *LocalSignal);
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_UnmapSignal
-**
-**  Unmap a signal mapped from another process.
-**
-**  INPUT:
-**
-**      gctSIGNAL Signal
-**          Pointer to the gctSIGNAL.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_UnmapSignal(
-    IN gctSIGNAL Signal
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmHEADER_ARG("Signal=0x%x", Signal);
-
-    gcmDEBUG_VERIFY_ARGUMENT(Signal != gcvNULL);
-
-    gcmTRACE_ZONE(
-        gcvLEVEL_VERBOSE, gcvZONE_OS,
-        "gcoOS_UnmapSignal: signal->%d.",
-        (gctINT)(gctUINTPTR_T)Signal
-        );
-    iface.ignoreTLS = gcvFALSE;
-    iface.command = gcvHAL_USER_SIGNAL;
-    iface.u.UserSignal.command = gcvUSER_SIGNAL_UNMAP;
-    iface.u.UserSignal.id      = (gctINT)(gctUINTPTR_T) Signal;
-
-    status = gcoOS_DeviceControl(gcvNULL,
-                                 IOCTL_GCHAL_INTERFACE,
-                                 &iface, gcmSIZEOF(iface),
-                                 &iface, gcmSIZEOF(iface));
-
-    gcmFOOTER();
-    return status;
-}
-
-
-void _SignalHandlerForSIGFPEWhenSignalCodeIs0(
-    int sig_num,
-    siginfo_t * info,
-    void * ucontext
-    )
-{
-    gctINT signalCode;
-
-    signalCode = ((info->si_code) & 0xffff);
-    if (signalCode == 0)
-    {
-        /* simply ignore the signal, this is a temporary fix for bug 4203 */
-        return;
-    }
-
-    /* Let OS handle the signal */
-    gcoOS_Print("Process got signal (%d). To further debug the issue, you should run in debug mode", sig_num);
-    signal (sig_num, SIG_DFL);
-    raise (sig_num);
-    return;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_AddSignalHandler
-**
-**  Adds Signal handler depending on Signal Handler Type
-**
-**  INPUT:
-**
-**      gceSignalHandlerType SignalHandlerType
-**          Type of handler to be added
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gcoOS_AddSignalHandler (
-    IN gceSignalHandlerType SignalHandlerType
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-
-    gcmHEADER_ARG("SignalHandlerType=0x%x", SignalHandlerType);
-
-    switch(SignalHandlerType)
-    {
-    case gcvHANDLE_SIGFPE_WHEN_SIGNAL_CODE_IS_0:
-        {
-#if gcdDEBUG
-                /* Handler will not be registered in debug mode*/
-                gcmTRACE(
-                    gcvLEVEL_INFO,
-                    "%s(%d): Will not register signal handler for type gcvHANDLE_SIGFPE_WHEN_SIGNAL_CODE_IS_0 in debug mode",
-                    __FUNCTION__, __LINE__
-                    );
-#else
-            struct sigaction temp;
-            struct sigaction sigact;
-            sigaction (SIGFPE, NULL, &temp);
-            if (temp.sa_handler != (void *)_SignalHandlerForSIGFPEWhenSignalCodeIs0)
-            {
-                sigact.sa_handler = (void *)_SignalHandlerForSIGFPEWhenSignalCodeIs0;
-                sigact.sa_flags = SA_RESTART | SA_SIGINFO;
-                sigemptyset(&sigact.sa_mask);
-                sigaction(SIGFPE, &sigact, (struct sigaction *)NULL);
-            }
-#endif
-            break;
-        }
-
-    default:
-        {
-            /* Unknown handler type */
-            gcmTRACE(
-                gcvLEVEL_ERROR,
-                "%s(%d): Cannot register a signal handler for type 0x%0x",
-                __FUNCTION__, __LINE__, SignalHandlerType
-                );
-            break;
-        }
-
-    }
-    gcmFOOTER();
-    return status;
-}
-
-gceSTATUS
-gcoOS_QueryCurrentProcessName(
-    OUT gctSTRING Name,
-    IN gctSIZE_T Size
-    )
-{
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gcoOS_DetectProcessByName
-**
-**  Detect if the current process is the executable specified.
-**
-**  INPUT:
-**
-**      gctCONST_STRING Name
-**          Name (full or partial) of executable.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**
-**  RETURN:
-**
-**      gcvSTATUS_TRUE
-**              if process is as specified by Name parameter.
-**      gcvSTATUS_FALSE
-**              Otherwise.
-**
-*/
-gceSTATUS
-gcoOS_DetectProcessByName(
-    IN gctCONST_STRING Name
-    )
-{
-    gctCHAR curProcessName[gcdMAX_PATH];
-    gceSTATUS status = gcvSTATUS_FALSE;
-
-    gcmHEADER_ARG("Name=%s", Name);
-
-    if (gcmIS_SUCCESS(gcoOS_QueryCurrentProcessName(curProcessName, gcdMAX_PATH)) &&
-        (gcoOS_StrStr(curProcessName, Name, gcvNULL) == gcvSTATUS_TRUE)
-       )
-    {
-        status = gcvSTATUS_TRUE;
-    }
-
-    gcmFOOTER();
-    return status;
-}
-
-gceSTATUS
-gcoOS_DetectProcessByEncryptedName(
-    IN gctCONST_STRING Name
-    )
-{
-    gceSTATUS status = gcvSTATUS_FALSE;
-    gctCHAR *p, buff[gcdMAX_PATH];
-    p = buff;
-
-    gcmONERROR(gcoOS_StrCopySafe(buff, gcdMAX_PATH, Name));
-
-    while (*p)
-    {
-        *p = ~(*p);
-        p++;
-    }
-
-    status = gcoOS_DetectProcessByName(buff);
-
-OnError:
-    return status;
-}
-
-gceSTATUS
-gcoOS_CPUPhysicalToGPUPhysical(
-    IN gctPHYS_ADDR_T CPUPhysical,
-    OUT gctPHYS_ADDR_T * GPUPhysical
-    )
-{
-    gctPHYS_ADDR_T cpuPhysical = CPUPhysical, gpuPhysical;
-
-    gcoOS os = gcPLS.os;
-    gcoPLATFORM platform;
-
-    gcmHEADER();
-    gcmVERIFY_ARGUMENT(os);
-
-    platform = &os->platform;
-
-    if (platform->ops->getGPUPhysical)
-    {
-        platform->ops->getGPUPhysical(platform, cpuPhysical, &gpuPhysical);
-
-        *GPUPhysical = (gctUINT32) gpuPhysical;
-    }
-    else
-    {
-        *GPUPhysical = CPUPhysical;
-    }
-
-    gcmFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-void
-gcoOS_RecordAllocation(void)
-{
-#if gcdGC355_MEM_PRINT
-    gcoOS os;
-    if (gcPLS.os != gcvNULL)
-    {
-        os = gcPLS.os;
-
-        os->oneSize = 0;
-        os->oneRecording = 1;
-    }
-#endif
-}
-
-gctINT32
-gcoOS_EndRecordAllocation(void)
-{
-    gctINT32   result = 0;
-#if gcdGC355_MEM_PRINT
-    gcoOS os;
-
-    if (gcPLS.os != gcvNULL)
-    {
-        os = gcPLS.os;
-
-        if (os->oneRecording == 1)
-        {
-            result = os->oneSize;
-
-            os->oneSize = 0;
-            os->oneRecording = 0;
-        }
-    }
-
-#endif
-    return result;
-}
-
-void
-gcoOS_AddRecordAllocation(gctSIZE_T Size)
-{
-#if gcdGC355_MEM_PRINT
-    gcoOS os;
-
-    if (gcPLS.os != gcvNULL)
-    {
-        os = gcPLS.os;
-
-        if (os->oneRecording == 1)
-        {
-            os->oneSize += (gctINT32)Size;
-        }
-    }
-#endif
-}
-
-gceSTATUS
-gcoOS_QuerySystemInfo(
-    IN gcoOS Os,
-    OUT gcsSystemInfo *Info
-    )
-{
-    /* SH cycles = MC cycles * (SH clock/MC clock).
-    ** Default value is 128 * 3 (cycles).
-    */
-    Info->memoryLatencySH = 128 * 3;
-
-    return gcvSTATUS_OK;
-}
-
-#if VIVANTE_PROFILER_SYSTEM_MEMORY
-
-gceSTATUS gcoOS_GetMemoryProfileInfo(size_t                      size,
-                                     struct _memory_profile_info *info)
-{
-    return gcvSTATUS_NOT_SUPPORTED;
-}
-
-#endif
index 68a6d8f2ce9e652728f286767eb2da9e1c3637c5..6348d4ef770af6883097325b4cedf97fa3e3c133 100644 (file)
@@ -40,5 +40,8 @@ LOCAL_MODULE       := galcore.ta
 LOCAL_MODULE_TAGS  := optional
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 LOCAL_MODULE_PATH  := $(TARGET_OUT_SHARED_LIBRARIES)/modules
+ifeq ($(PLATFORM_VENDOR),1)
+LOCAL_VENDOR_MODULE:= true
+endif
 include $(BUILD_PREBUILT)
 
index 730cc3e87e70493dd6570f706c08cde1bccb69a6..8fb08a78a40aed8906fda25d91b3b52f185d3bf1 100644 (file)
@@ -770,6 +770,7 @@ gctaHARDWARE_PrepareFunctions(
     gctUINT32 mmuBytes;
     gctUINT32 endBytes = 8;
     gctUINT8_PTR logical;
+    gctPHYS_ADDR_T physical;
 
     gcmkHEADER();
 
@@ -798,9 +799,11 @@ gctaHARDWARE_PrepareFunctions(
     gcmkONERROR(gctaOS_GetPhysicalAddress(
         Hardware->ta->os,
         Hardware->functionLogical,
-        (gctPHYS_ADDR_T *)&Hardware->functionAddress
+        &physical
         ));
 
+    gcmkSAFECASTPHYSADDRT(Hardware->functionAddress, physical);
+
     function = &Hardware->functions[0];
 
     function->logical = Hardware->functionLogical;
index c28e5a92b57177c27f50294e8406851787bf6ee4..8cad46c05622d942a5a073752446d63c1fbf918f 100644 (file)
@@ -222,9 +222,9 @@ _AllocateStlb(
     gcmkONERROR(gctaOS_GetPhysicalAddress(Os, stlb->logical, &stlb->physBase));
 
 #if gcdUSE_MMU_EXCEPTION
-    _FillPageTable(stlb->logical, stlb->size / 4, gcdMMU_STLB_EXCEPTION);
+    _FillPageTable(stlb->logical, (gctUINT32)stlb->size / 4, gcdMMU_STLB_EXCEPTION);
 #else
-    gctaOS_ZeroMemory(stlb->logical, stlb->size);
+    gctaOS_ZeroMemory(stlb->logical, (gctUINT32)stlb->size);
 #endif
 
     *Stlb = stlb;
@@ -272,15 +272,15 @@ gctaMMU_Construct(
         ));
 
 #if gcdUSE_MMU_EXCEPTION
-    _FillPageTable(mmu->mtlbLogical, mmu->mtlbBytes / 4, gcdMMU_STLB_EXCEPTION);
+    _FillPageTable(mmu->mtlbLogical, (gctUINT32)mmu->mtlbBytes / 4, gcdMMU_STLB_EXCEPTION);
 #else
-    gctaOS_ZeroMemory(mmu->mtlbLogical, mmu->mtlbBytes);
+    gctaOS_ZeroMemory(mmu->mtlbLogical, (gctUINT32)mmu->mtlbBytes);
 #endif
 
     /* Allocate a array to store stlbs. */
-    gcmkONERROR(gctaOS_Allocate(mmu->mtlbBytes, &mmu->stlbs));
+    gcmkONERROR(gctaOS_Allocate((gctUINT32)mmu->mtlbBytes, &mmu->stlbs));
 
-    gctaOS_ZeroMemory((gctUINT8_PTR)mmu->stlbs, mmu->mtlbBytes);
+    gctaOS_ZeroMemory((gctUINT8_PTR)mmu->stlbs, (gctUINT32)mmu->mtlbBytes);
 
     /* Allocate security safe page. */
     gcmkONERROR(gctaOS_AllocateSecurityMemory(
@@ -290,7 +290,7 @@ gctaMMU_Construct(
         &mmu->safePagePhysical
         ));
 
-    gctaOS_ZeroMemory((gctUINT8_PTR)mmu->safePageLogical, bytes);
+    gctaOS_ZeroMemory((gctUINT8_PTR)mmu->safePageLogical, (gctUINT32)bytes);
 
     /* Allocate non security safe page. */
     gcmkONERROR(gctaOS_AllocateSecurityMemory(
@@ -300,7 +300,7 @@ gctaMMU_Construct(
         &mmu->nonSecureSafePagePhysical
         ));
 
-    gctaOS_ZeroMemory((gctUINT8_PTR)mmu->nonSecureSafePageLogical, bytes);
+    gctaOS_ZeroMemory((gctUINT8_PTR)mmu->nonSecureSafePageLogical, (gctUINT32)bytes);
 
     /* gcmkONERROR(gctaOS_CreateMutex(TA->os, &mmu->mutex)); */
 
index a3cc25cf915ffc7b375bd0f807d04c5f0d9e39d7..c3339475df026969764f9ecfcc33ae537bcac55c 100644 (file)
@@ -217,7 +217,7 @@ gctaOS_GetPhysicalAddress(
 
     gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os->os, physical, &physical));
 
-    *Physical = (gctUINT32)physical;
+    *Physical = physical;
 
     return gcvSTATUS_OK;