Atlassian uses cookies to improve your browsing experience, perform analytics and research, and conduct advertising. Accept all cookies to indicate that you agree to our use of cookies on your device. Atlassian cookies and tracking notice, (opens new window)

Enlighten SDK 3.10 Documentation
Results will update as you type.
  • Welcome to Enlighten
  • How Enlighten works
  • Artist workflow
  • Install Enlighten
  • Libraries
  • Implementation guide
  • Technical reference
    • Output formats
    • Albedo handling
    • Lightmap lighting models
    • Light probe evaluation
    • Local IBL reflections
    • Light visibility data
    • Custom direct lights
    • Precompute pipeline
    • Low level precompute API
    • Debugging the precompute
    • The low level runtime
      • Low level runtime walkthrough
        • Preparing the runtime
          • Allocating working memory
          • Loading precomputed data
          • Providing albedo information
        • Per-frame walkthrough
        • Multiple systems at runtime
        • Low level cubemap API
      • Input lighting
      • Debug the low level runtime
    • Baked lighting
    • Performance tuning
    • Technical troubleshooting
    • Terrain LOD
    • Probe LOD
    • Lightmap LOD
  • Advanced techniques
  • Tools
  • Enlighten Mobile
  • White papers
  • Third-party licences
  • Release notes
    Calendars

You‘re viewing this with anonymous access, so some content might be blocked.
/
Allocating working memory

    This is the documentation for Enlighten.

    Allocating working memory

    Nov 21, 2019


    Overview

    This example demonstrates how to solve for the input lighting and output irradiance. Four additional temporary working memory buffers are required for the per-frame update loop:

    • One for the input lighting
    • One for the irradiance
    • One to receive the final output (persistent if using temporal solves)
    • One to receive the intermediate bounce output (persistent if using temporal solves)

    The intermediate bounce output is generated as a secondary output of the irradiance solver, and is used as the input to the EndInputLighting pass.

    When using temporal solves, the bounce output also accumulates lighting difference values; therefore it is necessary to use a unique persistent buffer for each system. The same applies to the final output textures since the temporal solver may only update this partially (or not at all) depending on the lighting changes.

    Setting up a memory allocator

    You must set a memory allocator before you can create or use any Enlighten object, including the IPrecompute object.
    This is a change from the behaviour of previous Enlighten releases.

    The file GeoBase/GeoMemory.h contains a virtual class MemoryAllocator and the associated function SetMemoryAllocator().

    Enlighten ships with a default memory allocator, GeoMemoryDefault, which is implemented using the standard C library memory functions. You can either use this allocator, or instead implement a custom allocator to tie into your own memory management or to track memory usage.

    Example using Enlighten's default memory allocator

    Use this code in your main function, to ensure that the memory allocator exists for the full duration of your program:

    Geo::GeoMemoryDefault alloc;
    Geo::SetMemoryAllocator(&alloc);
    
    Using a different memory allocator

    To use a different allocator, derive from the MemoryAllocator class and call SetMemoryAllocator() as above.

    The Enlighten runtime does not use the realloc function, so you can provide a dummy implementation for runtime use. However, if you are using the low-level precompute API then a proper implementation of realloc is required.

    Ensure correct alignment if you change the actual allocation/de-allocation; otherwise errors may occur.

    Working buffer for the input lighting

    The input lighting task requires a small amount of scratchspace working memory. It depends on the list of lights passed to the task to work out the size of the required buffer:

    // reserve workspace memory
    Geo::u32 workspaceSizeRequired = Enlighten::CalcRequiredScratchSpaceMemory(lights, numLights);
    void *   scratchMemory         = GEO_ALIGNED_MALLOC(workspaceSizeRequired, 16);
    

    When solving input lighting for many systems, simply allocate a single buffer large enough for the largest task and then reuse it.

    Working buffer for the solver

    The solve functions also require some scratchspace working memory. The size depends on a given system's budget and the number of dependencies. Use the RadSystemCore structure to query Enlighten and thus get a working buffer of exactly the right size:

    // reserve workspace memory
    Geo::u32 irradianceMemoryRequired = Enlighten::CalcRequiredIrradianceTaskWorkspaceMemory(&myRadSystemCore);
    void*    irradianceWorkspace      = GEO_ALIGNED_MALLOC(irradianceMemoryRequired, 128);
    

    Output texture buffers

    Allocate a buffer to receive the radiosity output:

    // Create radiosity output texture.
    Geo::s32 outputTextureSize       = radCore->m_MetaData.m_OutputWidth * radCore->m_MetaData.m_OutputHeight;
    Geo::s32 outputTextureMemorySize = outputTextureSize * 8; // fp16 output = 8 bytes per pixel
    
    void*    irradianceOutput        = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
    

    Optionally allocate buffer(s) for directional irradiance output:

    // Create directional output texture(s).
    Geo::s32 outputTextureSize       = radCore->m_MetaData.m_OutputWidth * radCore->m_MetaData.m_OutputHeight;
    Geo::s32 outputTextureMemorySize = outputTextureSize * 4; // 8 bit per channel output = 4 bytes per pixel
    
    // A single output texture for luminance-based directional irradiance
    void*    directionalOutput       = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
    
    // or alternatively, three output textures for colour-separated directional irradiance
    void*    directionalOutputR      = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
    void*    directionalOutputG      = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
    void*    directionalOutputB      = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
    

    The code sample above is simplified to assume a linear buffer with no extra padding per row (that is, the stride is set to the width). In practice, although the output texture has a width which is a multiple of 4, its data stride may be different to the actual width, depending on the graphics driver. In this case, it is more convenient to allocate the output buffer to be the same data size of the texture, and pass the appropriate stride to the Enlighten solver.

    Persistent data buffer

    Use the RadSystemCore to ask for the persistent data requirements:

    Geo::s32 bounceOutputSize = Enlighten::CalcRequiredPersistentDataSize(&myRadSystemCore);
    void*    bounceOutput     = GEO_ALIGNED_MALLOC(bounceOutputSize, 16);
    
    , multiple selections available,
    {"serverDuration": 20, "requestCorrelationId": "6ee4584a55764efba927e82ced97d1c3"}