Testing Uniform Buffer Read/Write Capabilities

You need the following Simdify® modules to complete this exercise: Simdify® Free Edition, Simdify® Compute Module, Simdify® Uniform Buffer Module

In this exercise you'll learn how to check if your GPU correctly reads and writes values to uniform buffers. Driver bugs are infrequent and these tests let you know if there are problems you should be aware of. It's also worth mentioning that Scenomics uses these tests to verify our OpenGL implementation. We've found plenty of our own bugs this way.

Start The Layout application

  1. Start the Layout app. (Start » Programs » Scenomics » Layout) or (Windows® key and then type 'Layout' to find the app icon.)

    The application displays a splash screen and then the application desktop appears.

    This is a picture of the desktop.

Run Uniform Buffer Write/Read Test Command

  1. Examine the main menu and select File » Run Tests.

    The application displays a list of tests that you can run.

  2. Select Spa.Test.UniformBuffers from the listed options and click OK or hit ENTER when you are finished.

    This is going to determine if your GPU is capable of reading and writing uniform buffer values correctly. Verification is performed by writing the values and then reading them back. We'll explore the test code later. Note that some GPUs do not support large shaders. If your GPU cannot compile this shader, you'll need to disable some of the code. That is discussed at the end of this exercise.

    
    //////////////////////////////////////////////////
    // Starting Uniform Buffer Tests
    //////////////////////////////////////////////////
    
    Found test GLSL: D:\Release6\Content\Tests\GPU\Uniform Buffer Read Write\test_uniform_buffer_read_write.glsl
    Setting up program to run compute shader using GLSL #version 430.
    Successfully compiled shader program.
    Successfully set shader program active on rendering device.
    Validated binding index: 'test_buffer' buffer index is: 0
    Validated buffer size: 'test_buffer' buffer size is 13600 bytes.
    Successfully created buffer 'test_buffer' on device.
    
    //////////////////////////////////////////////////
    test_bool
    //////////////////////////////////////////////////
    
    a_bWrite is: true
    a_bRead is:  true
    
    Result of memcmp(): 0 [ 0 = passed, any non-zero = fail ]
    
    a_oInfo.Name............................test_bool
    a_oInfo.TypeCode........................GL_BOOL_ARB
    a_oInfo.TypeName........................bool
    a_oInfo.Index...........................0
    a_oInfo.BufferIndex.....................0
    a_oInfo.BufferBinding...................-1
    a_oInfo.BufferType......................3
    a_oInfo.Location........................-1
    a_oInfo.Offset..........................0
    a_oInfo.Size............................1
    a_oInfo.Type............................0x8b56
    a_oInfo.TypeSize........................4
    a_oInfo.ArrayStride.....................0
    a_oInfo.MatrixStride....................0
    a_oInfo.Rows............................0
    a_oInfo.Cols............................0
    a_oInfo.RowMajor........................0
    a_oInfo.TopLevelArraySize...............0
    a_oInfo.TopLevelArrayStride.............0
    a_oInfo.IsMemberOfTopLevelArray.........0
    a_oInfo.IsMemberOfTopLevelUnsizedArray..0
    a_oInfo.GetTotalSize....................4
    
    //////////////////////////////////////////////////
    test_bool_array[0]
    //////////////////////////////////////////////////
    
    Write values:
    0,
    1,
    0,
    1
    
    Read values:
    0,
    1,
    0,
    1
    
    ...
    
    Executed: ApplicationRunTests
    
    test_bool test status: 0 [ 0 = passed, any non-zero = fail ]
    
    ...

    This is how you can verify that your hardware successfully reads and writes uniform buffers.

Get The Test Code Path

  1. Select File » Get Application Script Path... from the main menu.

    The software displays a dialog that allows you to select a script.

    This is a picture of the desktop.
  2. Type app_service_test_uniform_buffer_util.ssl and left click the script when it appears.
  3. Click OK or hit ENTER when you are finished.

    The software copies the full path to the script to the Windows¯ clipboard.

Examine The Test Code 'Execute' Function

  1. Start a text editor of your choice and select the option to open a file from disk.
  2. Select CTRL + V to paste the fragment shader file path (into the place in the dialog where you specify the file to open) and open the file.
  3. Use the text editor search feature to find a function named Execute. There are a few clearly delineated sections.
    1. Verify that required Simdify modules are available.
    2. Set up a shader program.
    3. Set up a shader buffer for testing.
    4. Set up a memory barrier.
    5. A section for testing a single function at a time.
    6. A section that performs all tests.
    ///////////////////////////////////////////////////////////////////////////////
    // function
    ///////////////////////////////////////////////////////////////////////////////
    
    function bool Execute( CommandPresentationModuleInfo commandInfo )
    {
       //////////////////////////////////////////////////
       // Verify Simdify-Package-Shader-Buffer exists.
       //////////////////////////////////////////////////
    
       if( !( SimdifyPackageShaderBuffer.Installed() ) )
       {
          string a_sPackage = SimdifyPackageShaderBuffer.GetName();
          string a_sMessage = "Required package <" + a_sPackage + "> is not installed.";
          LibAppServiceMessageBox.Alert( a_sMessage );
          return false;
       }
    
       //////////////////////////////////////////////////
       // Set up the shader program.
       //////////////////////////////////////////////////
    
       auto GpuTestDevice a_oParams;
    
       Render3D a_oAccel = Application.GetAccelerate3D();
       a_oParams.m_pAccel = a_oAccel;
    
       auto Program a_oProgram;
       a_oParams.m_pProgram = a_oProgram;
    
       // Create and bind the uniform buffer.
       a_oParams.m_sTestFolder = "Shader Buffer Read Write";
       a_oParams.m_sGlslTestFile = "test_shader_buffer_read_write.glsl";
       a_oParams.m_sBufferName = "test_buffer";
    
       a_oParams.m_slInfo.Add( LibAppServiceTest.Bar() );
       a_oParams.m_slInfo.Add( "// Starting Shader Buffer Tests" );
       a_oParams.m_slInfo.Add( LibAppServiceTest.Bar() );
       a_oParams.m_slInfo.AddBlank();
    
       bool a_bInit = LibAppServiceTest.Initialize( a_oParams );
       if( !( a_bInit ) )
       {
          return false;
       }
    
       Console.Clear();
    
       //////////////////////////////////////////////////
       // Create and bind the shader buffer.
       //////////////////////////////////////////////////
    
       auto ShaderBufferNode a_oShaderBuffer;
    
       auto ShaderBufferInfo a_oShaderBufferInfo;
       a_oShaderBufferInfo.m_pAccel = a_oAccel;
       a_oShaderBufferInfo.m_pRenderInfo = a_oParams.m_pRenderInfo;
       a_oShaderBufferInfo.m_pBuffer = a_oShaderBuffer;
       a_oShaderBufferInfo.m_pProgram = a_oProgram;
       a_oShaderBufferInfo.m_sBufferName = "test_buffer";
       a_oShaderBufferInfo.m_eBufferUsage = Enum.RBU_DynamicDraw();
    
       bool a_bCreatedBuffer = LibRender3D.CreateShaderBuffer(
          a_oShaderBufferInfo, a_oParams.m_slInfo );
    
       if( !( a_bCreatedBuffer ) )
       {
          a_oParams.m_slInfo.AddBlank();
          a_oParams.m_slInfo.Add( LibAssert.PrintCallStack() );
          LibAppServiceBuild.Out( a_oParams.m_slInfo );
          return false;
       }
    
       //////////////////////////////////////////////////
       // Set up the memory barrier.
       //////////////////////////////////////////////////
    
       // Since we're writing to a shader buffer, we
       // need to use a memory barrier between
       // accesses to the buffer.
       auto GpuMemoryBarrier m;
       m.GlShaderStorageBarrierBit = true;
    
       //////////////////////////////////////////////////
       // Declare subscripts for testing.
       //////////////////////////////////////////////////
    
       auto Int32Array a_aiSubs1;
       a_aiSubs1.Add( 2 );
    
       auto Int32Array a_aiSubs2;
       a_aiSubs2.Add( 2 );
       a_aiSubs2.Add( 3 );
    
       auto Int32Array a_aiSubs3;
       a_aiSubs3.Add( 2 );
       a_aiSubs3.Add( 3 );
       a_aiSubs3.Add( 4 );
    
       //////////////////////////////////////////////////
       // Execute single tests.
       //////////////////////////////////////////////////
    
       if( false )
       {
          TestFloat32MatrixArray( a_oParams, m, 2, 2, false, a_aiSubs1 );
    
          LibAppServiceBuild.Out( a_oParams.m_slInfo );
          Console.Out( "" );
          LibAppServiceBuild.Out( a_oParams.m_slTestStatus );
    
          // Do cleanup.
          //LibAppServiceMessageBox.Alert( "DESTROYING PROGRAM AND BUFFER!" );
          //Console.Out( a_oProgram.GetHandle() );
    
          a_oAccel.DeleteProgram( a_oProgram.GetHandle() );
          a_oAccel.DestroyShaderBuffer( a_oShaderBuffer.GetParams() );
          delete a_oParams.m_pRenderInfo;
    
          return false;
       }
    
       //////////////////////////////////////////////////
       // Execute all tests.
       //////////////////////////////////////////////////
    
       // Some of these tests require hardware that supports
       // the 8-bit signed/unsigned, 16-bit signed/unsigned
       // 16-bit FP, and 64-bit signed/unsigned extension.
    
       // Check extensions.
       RenderDeviceCaps a_oCaps = a_oAccel.GetDeviceCapabilities();
    
       bool a_bNvGpuShader5       = a_oCaps.QueryExtension( "GL_NV_gpu_shader5" );
       bool a_bAmdInt64           = a_oCaps.QueryExtension( "GL_AMD_gpu_shader_int64" );
       bool a_bArbInt64           = a_oCaps.QueryExtension( "GL_ARB_gpu_shader_int64" );
    
       bool a_bHighPrecInt  = a_bNvGpuShader5 || a_bAmdInt64 || a_bArbInt64;
       bool a_bLowPrecInt   = a_bNvGpuShader5;
       bool a_bLowPrecFloat = a_bNvGpuShader5;
    
       // Begin tests.
       TestBool( a_oParams, m );
       TestBoolArray( a_oParams, m, a_aiSubs1 );
       TestBoolArray( a_oParams, m, a_aiSubs2 );
       TestBoolArray( a_oParams, m, a_aiSubs3 );
       TestBoolVector( a_oParams, m, 2 );
       TestBoolVector( a_oParams, m, 3 );
       TestBoolVector( a_oParams, m, 4 );
       TestBoolVectorArray( a_oParams, m, 2, a_aiSubs1 );
       TestBoolVectorArray( a_oParams, m, 3, a_aiSubs1 );
       TestBoolVectorArray( a_oParams, m, 4, a_aiSubs1 );
       TestBoolVectorArray( a_oParams, m, 2, a_aiSubs2 );
       TestBoolVectorArray( a_oParams, m, 3, a_aiSubs2 );
       TestBoolVectorArray( a_oParams, m, 4, a_aiSubs2 );
       TestBoolVectorArray( a_oParams, m, 2, a_aiSubs3 );
       TestBoolVectorArray( a_oParams, m, 3, a_aiSubs3 );
       TestBoolVectorArray( a_oParams, m, 4, a_aiSubs3 );
    
       if( a_bLowPrecInt )
       {
          TestUint8( a_oParams, m );
          TestUint8Array( a_oParams, m, a_aiSubs1 );
          TestUint8Array( a_oParams, m, a_aiSubs2 );
          TestUint8Array( a_oParams, m, a_aiSubs3 );
          TestUint8Vector( a_oParams, m, 2 );
          TestUint8Vector( a_oParams, m, 3 );
          TestUint8Vector( a_oParams, m, 4 );
          TestUint8VectorArray( a_oParams, m, 2, a_aiSubs1 );
          TestUint8VectorArray( a_oParams, m, 3, a_aiSubs1 );
          TestUint8VectorArray( a_oParams, m, 4, a_aiSubs1 );
          TestUint8VectorArray( a_oParams, m, 2, a_aiSubs2 );
          TestUint8VectorArray( a_oParams, m, 3, a_aiSubs2 );
          TestUint8VectorArray( a_oParams, m, 4, a_aiSubs2 );
          TestUint8VectorArray( a_oParams, m, 2, a_aiSubs3 );
          TestUint8VectorArray( a_oParams, m, 3, a_aiSubs3 );
          TestUint8VectorArray( a_oParams, m, 4, a_aiSubs3 );
    
          TestUint16( a_oParams, m );
          TestUint16Array( a_oParams, m, a_aiSubs1 );
          TestUint16Array( a_oParams, m, a_aiSubs2 );
          TestUint16Array( a_oParams, m, a_aiSubs3 );
          TestUint16Vector( a_oParams, m, 2 );
          TestUint16Vector( a_oParams, m, 3 );
          TestUint16Vector( a_oParams, m, 4 );
          TestUint16VectorArray( a_oParams, m, 2, a_aiSubs1 );
          TestUint16VectorArray( a_oParams, m, 3, a_aiSubs1 );
          TestUint16VectorArray( a_oParams, m, 4, a_aiSubs1 );
          TestUint16VectorArray( a_oParams, m, 2, a_aiSubs2 );
          TestUint16VectorArray( a_oParams, m, 3, a_aiSubs2 );
          TestUint16VectorArray( a_oParams, m, 4, a_aiSubs2 );
          TestUint16VectorArray( a_oParams, m, 2, a_aiSubs3 );
          TestUint16VectorArray( a_oParams, m, 3, a_aiSubs3 );
          TestUint16VectorArray( a_oParams, m, 4, a_aiSubs3 );
       }
    
       TestUint32( a_oParams, m );
       TestUint32Array( a_oParams, m, a_aiSubs1 );
       TestUint32Array( a_oParams, m, a_aiSubs2 );
       TestUint32Array( a_oParams, m, a_aiSubs3 );
       TestUint32Vector( a_oParams, m, 2 );
       TestUint32Vector( a_oParams, m, 3 );
       TestUint32Vector( a_oParams, m, 4 );
       TestUint32VectorArray( a_oParams, m, 2, a_aiSubs1 );
       TestUint32VectorArray( a_oParams, m, 3, a_aiSubs1 );
       TestUint32VectorArray( a_oParams, m, 4, a_aiSubs1 );
       TestUint32VectorArray( a_oParams, m, 2, a_aiSubs2 );
       TestUint32VectorArray( a_oParams, m, 3, a_aiSubs2 );
       TestUint32VectorArray( a_oParams, m, 4, a_aiSubs2 );
       TestUint32VectorArray( a_oParams, m, 2, a_aiSubs3 );
       TestUint32VectorArray( a_oParams, m, 3, a_aiSubs3 );
       TestUint32VectorArray( a_oParams, m, 4, a_aiSubs3 );
    
       if( a_bHighPrecInt )
       {
          TestUint64( a_oParams, m );
          TestUint64Array( a_oParams, m, a_aiSubs1 );
          TestUint64Array( a_oParams, m, a_aiSubs2 );
          TestUint64Array( a_oParams, m, a_aiSubs3 );
          TestUint64Vector( a_oParams, m, 2 );
          TestUint64Vector( a_oParams, m, 3 );
          TestUint64Vector( a_oParams, m, 4 );
          TestUint64VectorArray( a_oParams, m, 2, a_aiSubs1 );
          TestUint64VectorArray( a_oParams, m, 3, a_aiSubs1 );
          TestUint64VectorArray( a_oParams, m, 4, a_aiSubs1 );
          TestUint64VectorArray( a_oParams, m, 2, a_aiSubs2 );
          TestUint64VectorArray( a_oParams, m, 3, a_aiSubs2 );
          TestUint64VectorArray( a_oParams, m, 4, a_aiSubs2 );
          TestUint64VectorArray( a_oParams, m, 2, a_aiSubs3 );
          TestUint64VectorArray( a_oParams, m, 3, a_aiSubs3 );
          TestUint64VectorArray( a_oParams, m, 4, a_aiSubs3 );
       }
    
       if( a_bLowPrecInt )
       {
          TestInt8( a_oParams, m );
          TestInt8Array( a_oParams, m, a_aiSubs1 );
          TestInt8Array( a_oParams, m, a_aiSubs2 );
          TestInt8Array( a_oParams, m, a_aiSubs3 );
          TestInt8Vector( a_oParams, m, 2 );
          TestInt8Vector( a_oParams, m, 3 );
          TestInt8Vector( a_oParams, m, 4 );
          TestInt8VectorArray( a_oParams, m, 2, a_aiSubs1 );
          TestInt8VectorArray( a_oParams, m, 3, a_aiSubs1 );
          TestInt8VectorArray( a_oParams, m, 4, a_aiSubs1 );
          TestInt8VectorArray( a_oParams, m, 2, a_aiSubs2 );
          TestInt8VectorArray( a_oParams, m, 3, a_aiSubs2 );
          TestInt8VectorArray( a_oParams, m, 4, a_aiSubs2 );
          TestInt8VectorArray( a_oParams, m, 2, a_aiSubs3 );
          TestInt8VectorArray( a_oParams, m, 3, a_aiSubs3 );
          TestInt8VectorArray( a_oParams, m, 4, a_aiSubs3 );
    
          TestInt16( a_oParams, m );
          TestInt16Array( a_oParams, m, a_aiSubs1 );
          TestInt16Array( a_oParams, m, a_aiSubs2 );
          TestInt16Array( a_oParams, m, a_aiSubs3 );
          TestInt16Vector( a_oParams, m, 2 );
          TestInt16Vector( a_oParams, m, 3 );
          TestInt16Vector( a_oParams, m, 4 );
          TestInt16VectorArray( a_oParams, m, 2, a_aiSubs1 );
          TestInt16VectorArray( a_oParams, m, 3, a_aiSubs1 );
          TestInt16VectorArray( a_oParams, m, 4, a_aiSubs1 );
          TestInt16VectorArray( a_oParams, m, 2, a_aiSubs2 );
          TestInt16VectorArray( a_oParams, m, 3, a_aiSubs2 );
          TestInt16VectorArray( a_oParams, m, 4, a_aiSubs2 );
          TestInt16VectorArray( a_oParams, m, 2, a_aiSubs3 );
          TestInt16VectorArray( a_oParams, m, 3, a_aiSubs3 );
          TestInt16VectorArray( a_oParams, m, 4, a_aiSubs3 );
       }
    
       TestInt32( a_oParams, m );
       TestInt32Array( a_oParams, m, a_aiSubs1 );
       TestInt32Array( a_oParams, m, a_aiSubs2 );
       TestInt32Array( a_oParams, m, a_aiSubs3 );
       TestInt32Vector( a_oParams, m, 2 );
       TestInt32Vector( a_oParams, m, 3 );
       TestInt32Vector( a_oParams, m, 4 );
       TestInt32VectorArray( a_oParams, m, 2, a_aiSubs1 );
       TestInt32VectorArray( a_oParams, m, 3, a_aiSubs1 );
       TestInt32VectorArray( a_oParams, m, 4, a_aiSubs1 );
       TestInt32VectorArray( a_oParams, m, 2, a_aiSubs2 );
       TestInt32VectorArray( a_oParams, m, 3, a_aiSubs2 );
       TestInt32VectorArray( a_oParams, m, 4, a_aiSubs2 );
       TestInt32VectorArray( a_oParams, m, 2, a_aiSubs3 );
       TestInt32VectorArray( a_oParams, m, 3, a_aiSubs3 );
       TestInt32VectorArray( a_oParams, m, 4, a_aiSubs3 );
    
       if( a_bHighPrecInt )
       {
          TestInt64( a_oParams, m );
          TestInt64Array( a_oParams, m, a_aiSubs1 );
          TestInt64Array( a_oParams, m, a_aiSubs2 );
          TestInt64Array( a_oParams, m, a_aiSubs3 );
          TestInt64Vector( a_oParams, m, 2 );
          TestInt64Vector( a_oParams, m, 3 );
          TestInt64Vector( a_oParams, m, 4 );
          TestInt64VectorArray( a_oParams, m, 2, a_aiSubs1 );
          TestInt64VectorArray( a_oParams, m, 3, a_aiSubs1 );
          TestInt64VectorArray( a_oParams, m, 4, a_aiSubs1 );
          TestInt64VectorArray( a_oParams, m, 2, a_aiSubs2 );
          TestInt64VectorArray( a_oParams, m, 3, a_aiSubs2 );
          TestInt64VectorArray( a_oParams, m, 4, a_aiSubs2 );
          TestInt64VectorArray( a_oParams, m, 2, a_aiSubs3 );
          TestInt64VectorArray( a_oParams, m, 3, a_aiSubs3 );
          TestInt64VectorArray( a_oParams, m, 4, a_aiSubs3 );
       }
    
       if( a_bLowPrecFloat )
       {
          TestFloat16( a_oParams, m );
          TestFloat16Array( a_oParams, m, a_aiSubs1 );
          TestFloat16Array( a_oParams, m, a_aiSubs2 );
          TestFloat16Array( a_oParams, m, a_aiSubs3 );
          TestFloat16Vector( a_oParams, m, 2 );
          TestFloat16Vector( a_oParams, m, 3 );
          TestFloat16Vector( a_oParams, m, 4 );
          TestFloat16VectorArray( a_oParams, m, 2, a_aiSubs1 );
          TestFloat16VectorArray( a_oParams, m, 3, a_aiSubs1 );
          TestFloat16VectorArray( a_oParams, m, 4, a_aiSubs1 );
          TestFloat16VectorArray( a_oParams, m, 2, a_aiSubs2 );
          TestFloat16VectorArray( a_oParams, m, 3, a_aiSubs2 );
          TestFloat16VectorArray( a_oParams, m, 4, a_aiSubs2 );
          TestFloat16VectorArray( a_oParams, m, 2, a_aiSubs3 );
          TestFloat16VectorArray( a_oParams, m, 3, a_aiSubs3 );
          TestFloat16VectorArray( a_oParams, m, 4, a_aiSubs3 );
       }
    
       TestFloat32( a_oParams, m );
       TestFloat32Array( a_oParams, m, a_aiSubs1 );
       TestFloat32Array( a_oParams, m, a_aiSubs2 );
       TestFloat32Array( a_oParams, m, a_aiSubs3 );
       TestFloat32Vector( a_oParams, m, 2 );
       TestFloat32Vector( a_oParams, m, 3 );
       TestFloat32Vector( a_oParams, m, 4 );
       TestFloat32VectorArray( a_oParams, m, 2, a_aiSubs1 );
       TestFloat32VectorArray( a_oParams, m, 3, a_aiSubs1 );
       TestFloat32VectorArray( a_oParams, m, 4, a_aiSubs1 );
       TestFloat32VectorArray( a_oParams, m, 2, a_aiSubs2 );
       TestFloat32VectorArray( a_oParams, m, 3, a_aiSubs2 );
       TestFloat32VectorArray( a_oParams, m, 4, a_aiSubs2 );
       TestFloat32VectorArray( a_oParams, m, 2, a_aiSubs3 );
       TestFloat32VectorArray( a_oParams, m, 3, a_aiSubs3 );
       TestFloat32VectorArray( a_oParams, m, 4, a_aiSubs3 );
    
       // Column Major
       TestFloat32Matrix( a_oParams, m, 2, 2, false );
       TestFloat32Matrix( a_oParams, m, 2, 3, false );
       TestFloat32Matrix( a_oParams, m, 2, 4, false );
       TestFloat32Matrix( a_oParams, m, 3, 2, false );
       TestFloat32Matrix( a_oParams, m, 3, 3, false );
       TestFloat32Matrix( a_oParams, m, 3, 4, false );
       TestFloat32Matrix( a_oParams, m, 4, 2, false );
       TestFloat32Matrix( a_oParams, m, 4, 3, false );
       TestFloat32Matrix( a_oParams, m, 4, 4, false );
    
       // Row Major
       TestFloat32Matrix( a_oParams, m, 2, 2, true );
       TestFloat32Matrix( a_oParams, m, 2, 3, true );
       TestFloat32Matrix( a_oParams, m, 2, 4, true );
       TestFloat32Matrix( a_oParams, m, 3, 2, true );
       TestFloat32Matrix( a_oParams, m, 3, 3, true );
       TestFloat32Matrix( a_oParams, m, 3, 4, true );
       TestFloat32Matrix( a_oParams, m, 4, 2, true );
       TestFloat32Matrix( a_oParams, m, 4, 3, true );
       TestFloat32Matrix( a_oParams, m, 4, 4, true );
    
       // Column Major
       TestFloat32MatrixArray( a_oParams, m, 2, 2, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 2, 2, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 2, 2, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 2, 3, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 2, 3, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 2, 3, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 2, 4, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 2, 4, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 2, 4, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 3, 2, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 3, 2, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 3, 2, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 3, 3, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 3, 3, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 3, 3, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 3, 4, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 3, 4, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 3, 4, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 4, 2, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 4, 2, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 4, 2, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 4, 3, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 4, 3, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 4, 3, false, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 4, 4, false, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 4, 4, false, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 4, 4, false, a_aiSubs3 );
    
       // Row Major
       TestFloat32MatrixArray( a_oParams, m, 2, 2, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 2, 2, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 2, 2, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 2, 3, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 2, 3, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 2, 3, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 2, 4, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 2, 4, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 2, 4, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 3, 2, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 3, 2, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 3, 2, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 3, 3, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 3, 3, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 3, 3, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 3, 4, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 3, 4, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 3, 4, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 4, 2, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 4, 2, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 4, 2, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 4, 3, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 4, 3, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 4, 3, true, a_aiSubs3 );
       TestFloat32MatrixArray( a_oParams, m, 4, 4, true, a_aiSubs1 );
       TestFloat32MatrixArray( a_oParams, m, 4, 4, true, a_aiSubs2 );
       TestFloat32MatrixArray( a_oParams, m, 4, 4, true, a_aiSubs3 );
    
       TestFloat64( a_oParams, m );
       TestFloat64Array( a_oParams, m, a_aiSubs1 );
       TestFloat64Array( a_oParams, m, a_aiSubs2 );
       TestFloat64Array( a_oParams, m, a_aiSubs3 );
       TestFloat64Vector( a_oParams, m, 2 );
       TestFloat64Vector( a_oParams, m, 3 );
       TestFloat64Vector( a_oParams, m, 4 );
       TestFloat64VectorArray( a_oParams, m, 2, a_aiSubs1 );
       TestFloat64VectorArray( a_oParams, m, 3, a_aiSubs1 );
       TestFloat64VectorArray( a_oParams, m, 4, a_aiSubs1 );
       TestFloat64VectorArray( a_oParams, m, 2, a_aiSubs2 );
       TestFloat64VectorArray( a_oParams, m, 3, a_aiSubs2 );
       TestFloat64VectorArray( a_oParams, m, 4, a_aiSubs2 );
       TestFloat64VectorArray( a_oParams, m, 2, a_aiSubs3 );
       TestFloat64VectorArray( a_oParams, m, 3, a_aiSubs3 );
       TestFloat64VectorArray( a_oParams, m, 4, a_aiSubs3 );
    
       // Column Major
       TestFloat64Matrix( a_oParams, m, 2, 2, false );
       TestFloat64Matrix( a_oParams, m, 2, 3, false );
       TestFloat64Matrix( a_oParams, m, 2, 4, false );
       TestFloat64Matrix( a_oParams, m, 3, 2, false );
       TestFloat64Matrix( a_oParams, m, 3, 3, false );
       TestFloat64Matrix( a_oParams, m, 3, 4, false );
       TestFloat64Matrix( a_oParams, m, 4, 2, false );
       TestFloat64Matrix( a_oParams, m, 4, 3, false );
       TestFloat64Matrix( a_oParams, m, 4, 4, false );
    
       // Row Major
       TestFloat64Matrix( a_oParams, m, 2, 2, true );
       TestFloat64Matrix( a_oParams, m, 2, 3, true );
       TestFloat64Matrix( a_oParams, m, 2, 4, true );
       TestFloat64Matrix( a_oParams, m, 3, 2, true );
       TestFloat64Matrix( a_oParams, m, 3, 3, true );
       TestFloat64Matrix( a_oParams, m, 3, 4, true );
       TestFloat64Matrix( a_oParams, m, 4, 2, true );
       TestFloat64Matrix( a_oParams, m, 4, 3, true );
       TestFloat64Matrix( a_oParams, m, 4, 4, true );
    
       // Column Major
       TestFloat64MatrixArray( a_oParams, m, 2, 2, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 2, 2, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 2, 2, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 2, 3, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 2, 3, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 2, 3, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 2, 4, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 2, 4, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 2, 4, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 3, 2, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 3, 2, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 3, 2, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 3, 3, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 3, 3, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 3, 3, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 3, 4, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 3, 4, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 3, 4, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 4, 2, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 4, 2, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 4, 2, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 4, 3, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 4, 3, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 4, 3, false, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 4, 4, false, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 4, 4, false, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 4, 4, false, a_aiSubs3 );
    
       // Row Major
       TestFloat64MatrixArray( a_oParams, m, 2, 2, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 2, 2, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 2, 2, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 2, 3, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 2, 3, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 2, 3, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 2, 4, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 2, 4, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 2, 4, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 3, 2, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 3, 2, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 3, 2, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 3, 3, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 3, 3, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 3, 3, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 3, 4, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 3, 4, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 3, 4, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 4, 2, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 4, 2, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 4, 2, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 4, 3, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 4, 3, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 4, 3, true, a_aiSubs3 );
       TestFloat64MatrixArray( a_oParams, m, 4, 4, true, a_aiSubs1 );
       TestFloat64MatrixArray( a_oParams, m, 4, 4, true, a_aiSubs2 );
       TestFloat64MatrixArray( a_oParams, m, 4, 4, true, a_aiSubs3 );
    
       // Do cleanup.
       //LibAppServiceMessageBox.Alert( "DESTROYING PROGRAM AND BUFFER!" );
       a_oAccel.DeleteProgram( a_oProgram.GetHandle() );
       a_oAccel.DestroyShaderBuffer( a_oShaderBuffer.GetParams() );
    
       delete a_oParams.m_pRenderInfo;
    
       //////////////////////////////////////////////////
       // Finis~
       //////////////////////////////////////////////////
    
       LibAppServiceBuild.Out( a_oParams.m_slInfo );
    
       Console.Blank();
       Console.Out( "Executed: " + Script.Runtime.CurrentFunction.Name );
       Console.Blank();
    
       LibAppServiceBuild.Out( a_oParams.m_slTestStatus );
    
       /*
       auto FilePath a_oTestOutputLogPath =
          new FilePath( "C:\\shader_buffer_log.txt" );
       WriteLog( a_oTestOutputLogPath, a_oParams.m_slTestStatus );
    
       auto FilePath a_oDetailsOutputLogPath =
          new FilePath( "C:\\shader_buffer_test_results.txt" );
       WriteLog( a_oDetailsOutputLogPath, a_oParams.m_slInfo );
       */
    
       return true;
    }

Examine The Test Code 'TestUint8VectorArray' Function

  1. Use the text editor search feature to find a function named TestUint8VectorArray. There are a few key sections.

    1. Create the variable name.
    2. Get reflection information for the buffer variable or return upon failure.
    3. Create the data we want to write and declare storage for the readback.
    4. Write data the device and execute the shader program.
    5. Read back the values that were written to the shader buffer variable during program execution.
    6. Print data.
    7. Print test results.
    8. Print shader buffer variable reflection information.

    ///////////////////////////////////////////////////////////////////////////////
    // function
    ///////////////////////////////////////////////////////////////////////////////
    
    function void TestUint8VectorArray( GpuTestDevice p_oTest, GpuMemoryBarrier m, int p_nVectorDim, Int32Array p_aiSubs )
    {
       string a_sName = CreateVectorArrayName( "test_u8vec", p_nVectorDim, p_aiSubs );
    
       LibAppServiceTest.MakeHeader(
          p_oTest.m_slInfo, a_sName, "" );
    
       auto ProgramConstantInfo a_oInfo;
       bool a_bValid = GetConstantInfo( p_oTest, a_oInfo, a_sName );
       if( !( a_bValid ) )
       {
          return;
       }
    
       ////////////////////////////////////////
       // Create Data
       ////////////////////////////////////////
    
       auto Uint8ArrayAlgorithms a_auAlgorithms;
       auto Uint8VectorArrayAlgorithms a_avuAlgorithms;
    
       int a_nCount = GetSubcriptsFactorial( p_aiSubs );
       auto Uint8VectorArray a_avDataIn = new Uint8VectorArray( a_nCount, 0, 0, 0, 0 );
       auto Uint8VectorArray a_avDataOut = new Uint8VectorArray( a_nCount, 0, 0, 0, 0 );
    
       auto Uint8ArrayView fill_view = a_avDataIn.GetView();
       fill_view.Last.Position = p_nVectorDim;
    
       int a_eVectorSpan = 4;
       uint a_nBase = 1;
       for( int f = 0; f < a_avDataIn.GetCount(); ++f )
       {
          a_auAlgorithms.Iota( fill_view.First, fill_view.Last, a_nBase );
    
          fill_view.First.Position += a_eVectorSpan;
          fill_view.Last.Position =
             fill_view.First.Position + p_nVectorDim;
          a_nBase += p_nVectorDim;
       }
    
       auto Uint8ArrayView src_view = a_avDataIn.GetView();
       auto Uint8ArrayView dst_view = a_avDataOut.GetView();
    
       ////////////////////////////////////////
       // Write Data
       ////////////////////////////////////////
    
       bool a_bZeroMemory = true;
    
       int a_nWriteSize = a_avuAlgorithms.GetWriteSizeInBytes(
          a_oInfo, src_view.First, src_view.Last, p_nVectorDim );
    
       auto Uint8Array a_auWrite;
       a_auWrite.ConvertBytesToCount( a_nWriteSize );
       auto Uint8ArrayView write_view = a_auWrite.GetView();
    
       a_avuAlgorithms.ConvertToGpuMemoryLayout(
          a_oInfo, a_bZeroMemory, p_nVectorDim,
          src_view.First, src_view.Last, write_view.First );
    
       auto MemoryPointer a_oSrcPtr = a_auWrite.GetPointer();
       //LibUint8Array.Out( a_auWrite );
    
       p_oTest.m_pAccel.WriteUniformSubBuffer(
          a_oInfo.Offset, a_oSrcPtr.SizeInBytes(), a_oSrcPtr );
    
       ////////////////////////////////////////
       // Execute Program
       ////////////////////////////////////////
    
       p_oTest.m_pAccel.ExecuteProgram( true, 128, 128, 1, 32, 32, 1 );
       p_oTest.m_pAccel.InsertMemoryBarrier( m );
    
       ////////////////////////////////////////
       // Read Data
       ////////////////////////////////////////
    
       auto Uint8Array a_auRead;
       a_auRead.Count = a_auWrite.GetCount();
       auto Uint8ArrayView read_view = a_auRead.GetView();
    
       auto MemoryPointer a_oDstPtr = a_auRead.GetPointer();
    
       p_oTest.m_pAccel.ReadUniformSubBuffer(
          a_oInfo.Offset, a_oDstPtr.SizeInBytes(), a_oDstPtr );
       //LibUint8Array.Out( a_auRead );
    
       a_avuAlgorithms.ConvertToCpuMemoryLayout(
          a_oInfo, a_bZeroMemory, p_nVectorDim,
          read_view.First, read_view.Last, dst_view.First );
       //LibUint8VectorArray.Out( a_avDataOut );
    
       ////////////////////////////////////////
       // Test Data
       ////////////////////////////////////////
    
       p_oTest.m_slInfo.Add( "Write values:" );
       LibUint8VectorArray.ConvertToString(
          a_avDataIn, 0, src_view.First.GetCount(), p_oTest.m_slInfo );
    
       p_oTest.m_slInfo.AddBlank();
    
       p_oTest.m_slInfo.Add( "Read values:" );
       LibUint8VectorArray.ConvertToString(
          a_avDataOut, 0, dst_view.First.GetCount(), p_oTest.m_slInfo );
    
       int a_nRes = a_auAlgorithms.Memcmp(
          src_view.First, dst_view.First, a_avDataIn.SizeInBytes() );
       LibAppServiceTest.DoMemcmp( p_oTest.m_slInfo, a_nRes );
    
       LibProgramConstantInfo.Print( a_oInfo, p_oTest.m_slInfo );
    
       p_oTest.m_slTestStatus.Add( a_sName + " test status: " +
          a_nRes + LibAppServiceTest.GetTestHint() );
    }