Project

General

Profile

« Previous | Next » 

Revision 344ac0e4

Added by Leszek Koltunski over 6 years ago

OIT: fix for 'out of memory' crash on Mali GPUs.

~The thing still does not fully work there - there are still strange flashes in apps that innvolve OIT, for example in 'Triblur'.

View differences:

src/main/java/org/distorted/library/main/DistortedEffects.java
78 78
    mAtomicCounter[0] = -1;
79 79
    }
80 80

  
81
  ///////////////////////////////////////////////////////////////
82
  // this has to be at least as big as the number of pixels in
83
  // the screen, lest the oitClear() pass overwrite memory.
81 84
  private static int mBufferSize=(0x1<<23);  // 8 million entries
82 85

  
83 86
  /// OIT CLEAR PROGRAM ///
......
126 129
///////////////////////////////////////////////////////////////////////////////////////////////////
127 130

  
128 131
  static void createProgram(Resources resources)
129
  throws FragmentCompilationException,VertexCompilationException,VertexUniformsException,FragmentUniformsException,LinkingException
130 132
    {
131 133
    // MAIN PROGRAM ////////////////////////////////////
132 134
    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
......
226 228
    if( mLinkedListSSBO[0]<0 )
227 229
      {
228 230
      GLES31.glGenBuffers(1,mLinkedListSSBO,0);
229
      GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER, 1, mLinkedListSSBO[0]);
230 231
      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]);
231 232
      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, mBufferSize*4 , null, GLES31.GL_DYNAMIC_READ|GLES31.GL_DYNAMIC_DRAW);
233
      GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER, 1, mLinkedListSSBO[0]);
232 234
      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);
233 235
      }
234 236

  
......
470 472
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
471 473
    GLES31.glUniform2f(mOITClearTexCorrH, 1.0f, 1.0f );   // corrections do not really matter here - only present because of common vertex shader.
472 474
    GLES31.glUniform1f( mOITClearDepthH , 1.0f);          // likewise depth
473
    GLES31.glUniform2f(mOITClearSizeH, surface.mWidth, surface.mHeight);
475
    GLES31.glUniform2ui(mOITClearSizeH, surface.mWidth, surface.mHeight);
474 476
    GLES31.glVertexAttribPointer(mOITClearProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
475 477
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
476 478
    }
......
486 488
    GLES31.glUniform1i(mOITBuildTextureH, 0);
487 489
    GLES31.glUniform1i(mOITBuildDepthTextureH, 1);
488 490
    GLES31.glUniform2f(mOITBuildTexCorrH, corrW, corrH );
489
    GLES31.glUniform2f(mOITBuildSizeH, surface.mWidth, surface.mHeight);
491
    GLES31.glUniform2ui(mOITBuildSizeH, surface.mWidth, surface.mHeight);
490 492
    GLES31.glUniform1ui(mOITBuildNumRecordsH, (mBufferSize-surface.mWidth*surface.mHeight)/3 );  // see the fragment shader
491 493
    GLES31.glUniform1f(mOITBuildDepthH , 1.0f-surface.mNear);
492 494
    GLES31.glVertexAttribPointer(mOITBuildProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
......
503 505
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
504 506
    GLES31.glUniform1i(mOITCollapseDepthTextureH, 1);
505 507
    GLES31.glUniform2f(mOITCollapseTexCorrH, corrW, corrH );
506
    GLES31.glUniform2f(mOITCollapseSizeH, surface.mWidth, surface.mHeight);
508
    GLES31.glUniform2ui(mOITCollapseSizeH, surface.mWidth, surface.mHeight);
507 509
    GLES31.glUniform1f( mOITCollapseDepthH , 1.0f-surface.mNear);
508 510
    GLES31.glVertexAttribPointer(mOITCollapseProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
509 511
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
......
518 520

  
519 521
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
520 522
    GLES31.glUniform2f(mOITRenderTexCorrH, corrW, corrH );
521
    GLES31.glUniform2f(mOITRenderSizeH, surface.mWidth, surface.mHeight);
523
    GLES31.glUniform2ui(mOITRenderSizeH, surface.mWidth, surface.mHeight);
522 524
    GLES31.glUniform1f( mOITRenderDepthH , 1.0f-surface.mNear);
523 525
    GLES31.glVertexAttribPointer(mOITRenderProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
524 526
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
525 527
    }
526 528

  
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

  
529
  private static void analyzeBuffer(int w, int h)
530
    {
531
    int ptr, index;
532
    int errors = 0;
533

  
534
    GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]);
535
    ByteBuffer buf = (ByteBuffer)GLES31.glMapBufferRange(GLES31.GL_SHADER_STORAGE_BUFFER, 0, mBufferSize*4, GLES31.GL_MAP_READ_BIT);
536
    IntBuffer intBuf = buf.order(ByteOrder.nativeOrder()).asIntBuffer();
537

  
538
    for(int col=0; col<w; col++)
539
      for(int row=0; row<h; row++)
540
        {
541
        index = col+row*w;
542
        ptr = intBuf.get(index);
543

  
544
        if( ptr!=0 )
545
          {
546
          if( ptr>0 && ptr<mBufferSize )
547
            {
548
            ptr = intBuf.get(ptr);
549
            if( ptr != index )
550
              {
551
              android.util.Log.d("surface", "col="+col+" row="+row+" val="+ptr+" expected: "+index);
552
              errors++;
553
              }
554
            }
555
          else
556
            {
557
            android.util.Log.d("surface", "overflow!");
558
            }
559
          }
560
        }
561

  
562
    GLES31.glUnmapBuffer(GLES31.GL_SHADER_STORAGE_BUFFER);
563
    GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);
564

  
565
    if( errors>0 ) android.util.Log.e("surface", "errors: "+errors);
566
    }
567

  
568 529
///////////////////////////////////////////////////////////////////////////////////////////////////
569 530

  
570 531
  private void releasePriv()
571 532
    {
572
    if( !matrixCloned   )   mM.abortAll(false);
573
    if( !vertexCloned   )   mV.abortAll(false);
574
    if( !fragmentCloned )   mF.abortAll(false);
575
    if( !postprocessCloned) mP.abortAll(false);
533
    if( !matrixCloned      ) mM.abortAll(false);
534
    if( !vertexCloned      ) mV.abortAll(false);
535
    if( !fragmentCloned    ) mF.abortAll(false);
536
    if( !postprocessCloned ) mP.abortAll(false);
576 537

  
577 538
    mM = null;
578 539
    mV = null;
src/main/java/org/distorted/library/main/DistortedOutputSurface.java
379 379
        {
380 380
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
381 381
        numRenders += child1.draw(time, this);
382

  
383
        //setAsOutput(time);
384
        //numRenders += child1.draw(time,this);
385 382
        }
386 383
      else
387 384
        {
src/main/res/raw/oit_build_fragment_shader.glsl
30 30
//////////////////////////////////////////////////////////////////////////////////////////////
31 31
// per-pixel linked list. Order Independent Transparency.
32 32

  
33
uniform vec2 u_Size;
33
uniform uvec2 u_Size;
34 34
uniform uint u_numRecords;
35 35

  
36 36
layout (binding=0, offset=0) uniform atomic_uint u_Counter;
......
53 53

  
54 54
  if( ptr<u_numRecords )
55 55
    {
56
    ptr = 3u*ptr + uint(u_Size.x*u_Size.y);
56
    ptr = 3u*ptr + u_Size.x*u_Size.y;
57 57

  
58 58
    u_Records[ptr+1u] = depth;
59 59
    u_Records[ptr+2u] = rgba;
60 60

  
61 61
    memoryBarrier();
62 62

  
63
    uint prev = uint(ij.x + ij.y * u_Size.x);
63
    uint prev = uint(ij.x) + uint(ij.y) * u_Size.x;
64 64
    uint curr = u_Records[prev];
65 65

  
66 66
    while (true)
src/main/res/raw/oit_clear_fragment_shader.glsl
26 26
//////////////////////////////////////////////////////////////////////////////////////////////
27 27
// per-pixel linked list. Order Independent Transparency.
28 28

  
29
uniform vec2 u_Size;
29
uniform uvec2 u_Size;
30 30

  
31 31
layout (std430,binding=1) buffer linkedlist  // first (u_Size.x*u_Size.y) uints - head pointers,
32 32
  {                                          // one for each pixel in the Output rectangle.
......
41 41

  
42 42
void main()                    		
43 43
  {
44
  uint index= uint(v_Pixel.x + v_Pixel.y * u_Size.x);
44
  uint index= uint(v_Pixel.x) + uint(v_Pixel.y) * u_Size.x;
45 45
  u_Records[index] = 0u;
46 46
  discard;
47 47
  }
src/main/res/raw/oit_collapse_fragment_shader.glsl
29 29
//////////////////////////////////////////////////////////////////////////////////////////////
30 30
// per-pixel linked list. Order Independent Transparency.
31 31

  
32
uniform vec2 u_Size;
32
uniform uvec2 u_Size;
33 33

  
34 34
layout (std430,binding=1) buffer linkedlist  // first (u_Size.x*u_Size.y) uints - head pointers,
35 35
  {                                          // one for each pixel in the Output rectangle.
......
42 42

  
43 43
void main()                    		
44 44
  {
45
  uint prev = uint(v_Pixel.x + v_Pixel.y * u_Size.x);
45
  uint prev = uint(v_Pixel.x) + uint(v_Pixel.y) * u_Size.x;
46 46
  uint curr = u_Records[prev];
47 47

  
48 48
  if (curr != 0u)
src/main/res/raw/oit_render_fragment_shader.glsl
27 27
//////////////////////////////////////////////////////////////////////////////////////////////
28 28
// per-pixel linked list. Order Independent Transparency.
29 29

  
30
uniform vec2 u_Size;
30
uniform uvec2 u_Size;
31 31

  
32 32
layout (std430,binding=1) buffer linkedlist  // first (u_Size.x*u_Size.y) uints - head pointers,
33 33
  {                                          // one for each pixel in the Output rectangle.
......
59 59

  
60 60
void main()                    		
61 61
  {
62
  uint prev = uint(v_Pixel.x + v_Pixel.y * u_Size.x);
62
  uint prev = uint(v_Pixel.x) + uint(v_Pixel.y) * u_Size.x;
63 63
  uint curr = u_Records[prev];
64 64

  
65 65
  if (curr != 0u)
src/main/res/raw/oit_vertex_shader.glsl
30 30
                              // reused!) so we need to compensate here by adjusting the texture
31 31
                              // coords.
32 32

  
33
uniform vec2 u_Size;          // size of the output surface, in pixels.
33
uniform uvec2 u_Size;         // size of the output surface, in pixels.
34 34

  
35 35
//////////////////////////////////////////////////////////////////////////////////////////////
36 36

  
37 37
void main()
38 38
  {
39 39
  v_TexCoordinate = (a_Position + 0.5) * u_TexCorr;
40
  v_Pixel         = (a_Position + 0.5) * u_Size;
40
  v_Pixel         = (a_Position + 0.5) * vec2(u_Size);
41 41
  gl_Position     = vec4(2.0*a_Position,u_Depth,1.0);
42 42
  }

Also available in: Unified diff