You need the following Simdify® modules to complete this exercise: Simdify® Free Edition
In this exercise you'll learn how to check if your GPU correctly sets uniform values (also referred to as shader constants). 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.
The application displays a splash screen and then the application desktop appears.
The application displays a list of tests that you can run.
This is going to determine that your GPU is capable of writing uniform values correctly. Verification is performed by writing the uniform values and then assigning them to variables of the same type declared in shader storage buffer objects. We'll explore the test code later.
Note that some GPUs do not support large shaders. For that reason some of the tests are disabled and will display error messages below. Don't worry about this. The tests can be enabled by editing the GLSL code.
//////////////////////////////////////////////////
// Starting Uniform Tests
//////////////////////////////////////////////////
Found test GLSL: D:\Release6\Content\Tests\GPU\Uniform Write\test_uniform_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 3600 bytes.
Successfully created buffer 'test_buffer' on device.
//////////////////////////////////////////////////
// Uniform Read/Write Test For: uniform_test_bool
//////////////////////////////////////////////////
Setting the following uniform constant:
a_oInfo.Name............................uniform_test_bool
a_oInfo.TypeCode........................GL_BOOL_ARB
a_oInfo.TypeName........................bool
a_oInfo.Index...........................0
a_oInfo.BufferIndex.....................-1
a_oInfo.BufferBinding...................-1
a_oInfo.BufferType......................3
a_oInfo.Location........................0
a_oInfo.Offset..........................-1
a_oInfo.Size............................1
a_oInfo.Type............................0x8b56
a_oInfo.TypeSize........................4
a_oInfo.ArrayStride.....................-1
a_oInfo.MatrixStride....................-1
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
a_bWrite is: true
a_bRead is: true
Result of memcmp(): 0 [ 0 = passed, any non-zero = fail ]
Uniform constant was assigned to this shader buffer variable in the GLSL code:
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......................4
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...............1
a_oInfo.TopLevelArrayStride.............0
a_oInfo.IsMemberOfTopLevelArray.........0
a_oInfo.IsMemberOfTopLevelUnsizedArray..0
a_oInfo.GetTotalSize....................4
...
The test results are pretty simple. There is a heading that indicates the variable being tested, followed by a table of information about the shader constant. This is program reflection information acquired from OpenGL and it can be very useful for diagnosing problems.
Next we have the write and read data, which clearly shows either success of failure, depending on the result of the test. This makes it much easier to determine the nature of any potential problems. The results of the memcmp function are displayed after the visual presentation of the test data.
Finally, in this test suite we are assigning the values of the uniforms we set to shader buffer variables so that we can read them back and perform comparisons. The last section contains program reflection information about the shader buffer variable used for the test. This is also useful for diagnosing tricky problems and bugs.
The software displays a dialog that allows you to select a script.
The software copies the full path to the script to the Windows® clipboard.
/////////////////////////////////////////////////////////////////////////////// // function /////////////////////////////////////////////////////////////////////////////// function bool Execute() { ////////////////////////////////////////////////// // Set up the shader program. ////////////////////////////////////////////////// auto GpuTestDevice a_oTest; Render3D a_oAccel = Application.GetAccelerate3D(); a_oTest.m_pAccel = a_oAccel; auto Program a_oProgram; a_oTest.m_pProgram = a_oProgram; // Create and bind the uniform buffer. a_oTest.m_sGlslTestFile = "test_uniform_write.glsl"; a_oTest.m_sBufferName = "test_buffer"; a_oTest.m_slInfo.Add( LibAppServiceTest.Bar() ); a_oTest.m_slInfo.Add( "// Starting Uniform Tests" ); a_oTest.m_slInfo.Add( LibAppServiceTest.Bar() ); a_oTest.m_slInfo.AddBlank(); bool a_bInit = LibAppServiceTest.Initialize( a_oTest ); 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_oTest.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_oTest.m_slInfo ); if( !( a_bCreatedBuffer ) ) { a_oTest.m_slInfo.AddBlank(); a_oTest.m_slInfo.Add( LibAssert.PrintCallStack() ); LibAppServiceBuild.Out( a_oTest.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 MemoryBarrier m; m.GlShaderStorageBarrierBit = true; ////////////////////////////////////////////////// // Execute single tests. ////////////////////////////////////////////////// if( false ) { TestUniformFloat64Matrix( a_oTest, 2, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 2, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 2, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 3, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 3, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 3, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 4, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 4, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 4, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); LibAppServiceBuild.Out( a_oTest.m_slInfo ); // LEAVE THIS HERE. a_oTest.m_pAccel.DeleteProgram( a_oProgram.GetHandle() ); a_oTest.m_pAccel.DestroyShaderBuffer( a_oShaderBuffer.GetParams() ); delete a_oTest.m_pRenderInfo; return false; } ////////////////////////////////////////////////// // Execute all tests. ////////////////////////////////////////////////// TestUniformBool( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformBoolArray( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformBoolVector( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformBoolVector( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformBoolVector( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformBoolVectorArray( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformBoolVectorArray( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformBoolVectorArray( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32Array( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32Vector( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32Vector( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32Vector( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32VectorArray( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32VectorArray( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint32VectorArray( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64Array( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64Vector( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64Vector( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64Vector( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64VectorArray( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64VectorArray( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformUint64VectorArray( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32Array( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32Vector( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32Vector( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32Vector( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32VectorArray( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32VectorArray( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt32VectorArray( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64Array( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64Vector( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64Vector( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64Vector( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64VectorArray( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64VectorArray( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformInt64VectorArray( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Array( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Vector( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Vector( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Vector( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32VectorArray( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32VectorArray( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32VectorArray( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 2, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 2, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 2, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 3, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 3, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 3, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 4, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 4, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32Matrix( a_oTest, 4, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 2, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 2, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 2, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 3, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 3, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 3, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 4, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 4, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat32MatrixArray( a_oTest, 4, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Array( a_oTest ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Vector( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Vector( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Vector( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64VectorArray( a_oTest, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64VectorArray( a_oTest, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64VectorArray( a_oTest, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 2, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 2, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 2, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 3, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 3, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 3, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 4, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 4, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64Matrix( a_oTest, 4, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 2, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 2, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 2, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 3, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 3, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 3, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 4, 2 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 4, 3 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); TestUniformFloat64MatrixArray( a_oTest, 4, 4 ); a_oTest.m_pAccel.InsertMemoryBarrier( m ); // Do cleanup. a_oTest.m_pAccel.DeleteProgram( a_oProgram.GetHandle() ); a_oTest.m_pAccel.DestroyShaderBuffer( a_oShaderBuffer.GetParams() ); delete a_oTest.m_pRenderInfo; ////////////////////////////////////////////////// // Finis~ ////////////////////////////////////////////////// LibAppServiceBuild.Out( a_oTest.m_slInfo ); Console.Blank(); Console.Out( "Executed: " + Script.Runtime.CurrentFunction.Name ); return true; }
///////////////////////////////////////////////////////////////////////////////
// function
///////////////////////////////////////////////////////////////////////////////
function void TestUniformFloat64VectorArray( GpuTestDevice p_oTest, int p_nVectorDim )
{
//////////////////////////////////////////////////
// Create variable name.
//////////////////////////////////////////////////
string a_sVariable = "test_dvec" + p_nVectorDim + "_array[0]";
string a_sUniformName = "uniform_" + a_sVariable;
//////////////////////////////////////////////////
// Initialize uniform.
//////////////////////////////////////////////////
auto ProgramConstantInfo a_oUniformInfo;
bool a_bInit = LibAppServiceTest.InitializeUniform(
p_oTest.m_pAccel, p_oTest.m_pProgram, a_sUniformName,
a_oUniformInfo, p_oTest.m_slInfo );
if( !( a_bInit ) )
{
return;
}
//////////////////////////////////////////////////
// Create the data we want to write and declare storage for the readback
//////////////////////////////////////////////////
auto Float64VectorArray a_avWrite;
auto Float64Vector wa = new Float64Vector( 0.1, 1.2, 2.3, 3.4 );
auto Float64Vector wb = new Float64Vector( 4.4, 5.3, 6.2, 7.1 );
auto Float64Vector wc = new Float64Vector( 8.1, 9.2, 10.3, 11.4 );
auto Float64Vector wd = new Float64Vector( 12.4, 13.3, 14.2, 15.1 );
a_avWrite.Add( wa );
a_avWrite.Add( wb );
a_avWrite.Add( wc );
a_avWrite.Add( wd );
auto Float64VectorArray a_avRead;
auto Float64Vector ra = new Float64Vector( 0, 0, 0, 0 );
auto Float64Vector rb = new Float64Vector( 0, 0, 0, 0 );
auto Float64Vector rc = new Float64Vector( 0, 0, 0, 0 );
auto Float64Vector rd = new Float64Vector( 0, 0, 0, 0 );
a_avRead.Add( ra );
a_avRead.Add( rb );
a_avRead.Add( rc );
a_avRead.Add( rd );
auto Float64ArrayView src_view = a_avWrite.GetView();
auto Float64ArrayView dst_view = a_avRead.GetView();
// For vec2 or vec3, we need to clear some
// values so that we can be sure our write
// and read data is minimal and clean.
for( int v = 0; v < a_avWrite.GetCount(); ++v )
{
Float64Vector a_vVector = a_avWrite.Get( v );
for( int s = p_nVectorDim; s < Enum.GLSL_DataType_Vec4(); ++s )
{
a_vVector.SetComponent( s, 0 );
}
}
//////////////////////////////////////////////////
// Set the uniform on the device and execute the shader program.
//////////////////////////////////////////////////
auto Float64ArrayAlgorithms fa;
auto Float64VectorArrayAlgorithms va;
p_oTest.m_pAccel.SetProgramConstantFloat64VectorArray(
p_oTest.m_pProgram.GetHandle(), a_oUniformInfo.Location,
a_avWrite, p_nVectorDim, a_avWrite.GetCount() );
p_oTest.m_pAccel.ExecuteProgram( true, 128, 128, 1, 32, 32, 1 );
//////////////////////////////////////////////////
// Get reflection information (constant info) for the shader buffer variable.
//////////////////////////////////////////////////
auto ProgramConstantInfo a_oBufferInfo;
p_oTest.m_pAccel.GetProgramConstantInfo(
p_oTest.m_pProgram.GetHandle(), a_sVariable, a_oBufferInfo );
//////////////////////////////////////////////////
// Read back the value of the uniform that was written to the shader buffer variable during program execution.
//////////////////////////////////////////////////
// All vec3 uniforms are aligned to 16-bytes
// so we have to do the readback as if we
// are reading back a vec4.
if( p_nVectorDim == Enum.GLSL_DataType_Vec3() )
{
p_nVectorDim = Enum.GLSL_DataType_Vec4();
}
int a_nSize = SizeLimits.sizeof_float64() *
p_nVectorDim * a_avWrite.GetCount();
auto Float64Array a_afReadData = new Float64Array(
p_nVectorDim * a_avWrite.GetCount(), 0 );
auto Float64ArrayView read_view = a_afReadData.GetView();
auto MemoryPointer a_oDstPtr = a_afReadData.GetPointer();
p_oTest.m_pAccel.ReadShaderSubBuffer(
a_oBufferInfo.Offset, a_afReadData.SizeInBytes(), a_oDstPtr );
va.PackScalarArrayInVectors(
read_view.First, read_view.Last, dst_view.First, p_nVectorDim );
//////////////////////////////////////////////////
// Print data.
//////////////////////////////////////////////////
p_oTest.m_slInfo.AddBlank();
p_oTest.m_slInfo.Add( "Write values:" );
LibFloat64VectorArray.ConvertToString(
a_avWrite, 0, a_avWrite.GetCount(), p_oTest.m_slInfo );
p_oTest.m_slInfo.AddBlank();
p_oTest.m_slInfo.Add( "Read values:" );
LibFloat64VectorArray.ConvertToString(
a_avRead, 0, a_avRead.GetCount(), p_oTest.m_slInfo );
//////////////////////////////////////////////////
// Print test results.
//////////////////////////////////////////////////
LibAppServiceTest.DoMemcmp( p_oTest.m_slInfo,
fa.Memcmp( src_view.First, dst_view.First, a_nSize ) );
//////////////////////////////////////////////////
// Print shader buffer variable reflection information.
//////////////////////////////////////////////////
GetBufferCopyMessage( p_oTest.m_slInfo );
LibProgramConstantInfo.Print( a_oBufferInfo, p_oTest.m_slInfo );
}