sales@scenomics.com +1 650 396 9674

Change Log
Added SPA_Vendor.glsl to the GLSL includes directory. SPA_Vendor.glsl contains #define statements for the big three vendors, NVIDIA, AMD, and INTEL. You can use the #define statements to write code for specific device manufacturers, or to fence code off from specific device manufacturers.
Fixed a bug in the new <DataCapture> wizard. At the end, when we set the container pointers for the new <DataCapture> objects, we set the container pointers to the <VariableNode> that was in the memento state (for undo). We need to set the containers to the unedited <VariableNode> we are editing.
Fixed name collisions in dynamically-generated interface items for the <ShaderBufferBindNode> and <UniformBufferBindNode>. Please see TYPE_SHADER_BUFFER_BIND_NODE_SCRIPTS.SSL and TYPE_UNIFORM_BUFFER_BIND_NODE_SCRIPTS.SSL for more information.
Fixed a bug in macro TextureSetPixelFormat(). Previously the test for whether or not a <Texture> was internal (stores <Image> objects inside the <Texture>) or external (referring to a file on disk) was not quite precise enough.
Iterator Changes

Completed Phase 1 of the conversion to iterator-based algorithms. This included targeted refactoring of the Scenome Scripting Language codebase and testing of all affected systems.

Historically, Scenome Scripting Language was designed to be a simple way to modify a Scenome application that did not require the user to write C++ code. And we wanted to keep it very simple, focused naturally on very high-level tasks such as implementing commands or test systems. Of course that's not exactly how things turned out. Even large Scenome Scripting Language codebases compile in a matter of seconds, and incredibly fast builds turned out to be highly-desirable for developers. As the language grew, we faced increasing desire for high-performance low level operations, and the need for the language to be 'simple' became a secondary objective. From its initial start as a language for writing commands for Scenome applications, Scenome Scripting Language has become an integral part of the entire product experience.

As the Scenome Scripting Language codebase has grown, the need for performance and flexibility has also grown. Previously, algorithm support, such as for filling or copying arrays, was performed with the array algorithms data interface for the relevant type. This was done with the idea that it's important to keep the language simple and easy to learn, in keeping with the principles outlined above.

For example: <Float32ArrayAlgorithms> had data interfaces for consuming all other scalar, scalar array, vector, vector array, or matrix types, as well as algorithms such as linear interpolate and iota. Algorithms in <Float32ArrayAlgorithms> accepted <Float32Array> objects as parameters, and algorithms in <Int8ArrayAlgorithms> accepted <Int8Array> objects as parameters.


   auto Float32ArrayAlgorithmms a_afAlgs;

   auto Float32Array src;
   src.Count = 32;

   a_afAlgs.ConsumeFloat32( src, 1.5 );

   // Do a copy/convert to Int32Array...
   auto Int32ArrayAlgorithms a_aiAlgs;

   auto Int32Array dst;
   dst.Count = src.GetCount();
   a_aiAlgs.ConsumeFloat32Array( src );

   // Or maybe...
   a_aiAlgs.ConsumeInt8Array( /*some Int8Array*/ );
   // Or maybe...
   a_aiAlgs.ConsumeFloat32VectorArray( /*some Float32Array*/ );
            

To use iterators you simply declare them with auto as shown below. Then you bind the iterator to an object using SSL::GetIterators( FirstIterator f, LastIterator l ). Note that these are forward iterators only. Backward iteration is not supported at present, but that might change in the future depending on use cases.


   auto Float32ArrayAlgorithms a_afAlgs;

   auto Float32Array fsrc;
   fsrc.Count = 32;
   auto Float32Iterator fsrc_beg;
   auto Float32Iterator fsrc_end;
   fsrc.GetIterators( fsrc_beg, fsrc_end );

   auto Float32Iterator fill;
   fill.Data = 1.5;

   a_afAlgs.Fill( fsrc_beg, fsrc_end, fill );

   LibFloat32Array.Out( fsrc );

   // And then...

   auto Int32ArrayAlgorithms a_aiAlgs;

   auto Int32Array idst;
   idst.Count = fsrc.GetCount();
   auto Int32Iterator idst_beg;
   auto Int32Iterator idst_end;
   idst.GetIterators( idst_beg, idst_end );

   a_aiAlgs.Copy( fsrc_beg, fsrc_end, idst_beg );

   LibInt32Array.Out( idst );
            

At first glance the iterator code looks more verbose—;and it is. However the iterator based system offers performance, flexibility, and interoperability that the old 'custom algorithm for every use case' cannot match. Here we're using the iterator position values to implement a very fine-grained copy operation. Iterator-based algorithms have a flexibility and programmability that algorithms with fixed signatures cannot hope to match.


   auto Float32ArrayAlgorithms a_afAlgs;

   auto Float32Array fsrc;
   fsrc.Count = 32;
   auto Float32Iterator fsrc_beg;
   auto Float32Iterator fsrc_end;
   fsrc.GetIterators( fsrc_beg, fsrc_end );

   auto Float32Iterator fsrc_fill;
   fsrc_fill.Data = 1.5;

   a_afAlgs.Fill( fsrc_beg, fsrc_end, fsrc_fill );

   LibFloat32Array.Out( fsrc );

   // And then...

   auto Int32ArrayAlgorithms a_aiAlgs;

   auto Int32Array idst;
   idst.Count = fsrc.GetCount();
   auto Int32Iterator idst_beg;
   auto Int32Iterator idst_end;
   idst.GetIterators( idst_beg, idst_end );

   auto Int32Iterator idst_fill;
   idst_fill.Data = 0;

   a_aiAlgs.Fill( idst_beg, idst_end, idst_fill );

   // Set the range of the source to index 2 to 4.
   fsrc_beg.Position = 2;
   fsrc_end.Position = 4;

   // Set the range of the destination to index 18 to 20.
   idst_beg.Position = 18;
   idst_end.Position = 20;

   a_aiAlgs.Copy( fsrc_beg, fsrc_end, idst_beg );

   LibInt32Array.Out( idst );
            

The change to iterator-based algorithms enables numerous simplifications in Scenome Scripting Language client code. For example, the highly-desired ability to iterate over (and mutate) an <Image> object's individual values is now reality.


   // This is a macro where the user has a <Texture> node selected.
   // We're going to iterate over a range of values in the underlying <Texture> object.
   Texture a_oTexture = LibSelect.FirstTexture();
   Image a_oImage = a_oTexture.GetFirstImage();

   if( a_oImage.PixelFormat == Enum.IPF_FP32x4() )
   {
      // Declare and bind forward
      // iterators for the <Image> object.
      auto Float32Iterator image_first;
      auto Float32Iterator image_last;
      a_oImage.GetIterators( image_first, image_last );
      image_last.Position = 1024; // Set the final iterator position.

      // Print values between image_first.Position (which is at position 0)
      // and image_last.Position (which is at position 1024).
      while( image_first.Position != image_last.Position )
      {
         Console.Out( image_first.Value );
         ++image_first.Position; // Increment the iterator.
         // We could also do...
         // image_first.Value = 1.0;
      }
   }
            

It's very common to work with iterators in pairs that define ranges. Note that any iterator pair passed into a function must refer to the same object. The following is not allowed:


   auto Float32ArrayAlgorithms a_afAlgs;

   auto Float32Array fsrca;
   fsrca.Count = 8;
   auto Float32Iterator fsrca_beg;
   fsrca.GetIterators( fsrca_beg, null );

   auto Float32Iterator fill;
   fill.Data = 1.5;

   auto Float32Array fsrcb;
   fsrcb.Count = 8;
   auto Float32Iterator fsrcb_end;
   fsrca.GetIterators( null, fsrcb_end );

   a_afAlgs.Fill( fsrca_beg, fsrcb_end, fill ); // This WILL fail.

   LibFloat32Array.Out( fsrca );
            

As with their C++ counterparts, it's possible to invalidate iterators and the results can be unpredictable. If you increase the underlying allocation, your iterator range will be short compared to the underlying object, but the iterators may remain stable. If you decrease the size of the underlying object, attempting to dereference your iterators may cause the application to crash. Consider iteration invalidation as undefined behavior in Scenome Scripting Language until further guidance is issued.

In nearly all cases, performance of these algorithms vastly exceeds performance of the previous system.

Iterator Types
<Int8Iterator> : public <TypedIterator>
<Int16Iterator> : public <TypedIterator>
<Int32Iterator> : public <TypedIterator>
<Int64Iterator> : public <TypedIterator>
<Uint8Iterator> : public <TypedIterator>
<Uint16Iterator> : public <TypedIterator>
<Uint32Iterator> : public <TypedIterator>
<Uint64Iterator> : public <TypedIterator>
<Float16Iterator> : public <TypedIterator>
<Float32Iterator> : public <TypedIterator>
<Float64Iterator> : public <TypedIterator>
Iterator Support Supported
<Image> Yes
<Int8Array> Yes
<Int16Array> Yes
<Int32Array> Yes
<Int64Array> Yes
<Uint8Array> Yes
<Uint16Array> Yes
<Uint32Array> Yes
<Uint64Array> Yes
<Float16Array> Yes
<Float32Array> Yes
<Float64Array> Yes
<Float32Matrix> Yes
<Float64Matrix> Yes
<Float32MatrixArray> No. Probably Scenome 21.7 or Scenome 21.8.
<Float64MatrixArray> No. Probably Scenome 21.7 or Scenome 21.8.