Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 15 of 15

Thread: Gemotry Pass to cullin & Transform Feeedback Buffers

  1. #11
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    10
    Quote Originally Posted by Dark Photon View Post
    Also, a few questions:

    1. In your "And DrawCalls of Feedback Process", I don't see you setting up the GL_ARRAY_BUFFER binding here before glDrawArrays(). Are you sure it is set properly at this point? The Transform Feedback object doesn't capture the GL_ARRAY_BUFFER binding (and so doesn't restore it when the TF object is bound).
    2. For glTransformFeedbackVaryings(), are you calling it before you link your glLinkProgram() for the transform feedback program?
    1. Yes, indeed, I was forgetting. (but there are still many things wrong).
    2. I am using glTransformFeedbackVaryings() between to load shader Programs and create FeedbackObject.


    Quote Originally Posted by Dark Photon View Post
    On the topic of TF setup, I am puzzled by your code here. Your TF shader shows that you are outputting to 2 streams. However, you're only binding a buffer object to receive TF output on stream 0 (i.e. GL_TRANSFORM_FEEDBACK_BUFFER[ 0 ]). Why?
    I thought I could use only a single buffer, selecting a INTERVELAVED mode.

    As you can obviously verify I have a big mess of concepts, even so between all the documentation and your responses I can go enlightening everything, I think I'm close.
    Code :
    //
    glBindBuffer(GL_ARRAY_BUFFER, Buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Data_Max_Storage), 0, GL_STREAM_DRAW);
     
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, Feedback);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, Buffer);
    //
    1. When I create the transform feedback object that first that I made is bind him with a GL_ARRAY_BUFFER with a maximum size equivalent to all the information that may contain, leaving it empty, This is Right?
    2. I must use glBindBufferBase() for set each Stream in to a unique Buffer? I do not need to indicate how much space has each one?

      Quote Originally Posted by Dark Photon View Post
      It depends on the method you choose for getting your TF output counts (1 for each stream) into the indirect draw call buffer(s). But in general:

      copy the TF output counts into the proper locations (on top of the "instanceCount" members) in the indirect draw call buffer(s) (if you don't write them there directly during TF),
      bind the buffer to the GL_INDIRECT_BUFFER buffer bind point, and then
      issue the indirect draw call (e.g. glMultiDrawArraysIndirect).
    3. This includes using glMultiDrawElementsIndirectCount() from ARB_indirect_parameters?, when you says "(on top of the "instanceCount" members) in the indirect draw call buffer(s)" this means that I have to bind GL_INDIRECT_BUFFER with Tranform Feedback Object too?

      [srry if it sounds stupid]
    4. How I can made the output counts on geometry step to use with GL_INDIRECT_BUFFER?
    5. I canīt find examples codes / or exercises from 4.4Core about Transform Feedback, as a way to learn, would it be possible share some code that you have?

  2. #12
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,478
    Quote Originally Posted by martel View Post
    I thought I could use only a single buffer, selecting a INTERVELAVED mode.
    Well check the spec, but IIRC the way it works is (considering only 1 output stream): SEPARATE writes each TF output to its own separate buffer bind point, whereas INTERLEAVED interleaves them all into the same buffer (bound to a single buffer bind point). That's for a single output stream. With multiple output streams, you have more flexibility and can interleave the outputs written to a each stream in their own buffer, but you still have each separate stream filling its own output buffer. So the buffer for each stream is bound to its own indexed buffer bind point (using glBindBufferBase or glBindBufferRange).

    For reference, see Transform Feedback in the wiki. In particular, the Advanced Interleaving section.

    Also check the OpenGL Spec. In particular, pg. 449 where it's talking about when a program can fail to link due to a call to glTransformFeedbackVaryings(), it says one way this can happen is if: "the set of outputs to capture to any single binding point includes outputs from more than one vertex stream." So your streams will be routed to the buffers bound to separate binding points, one per stream.

    When I create the transform feedback object that first that I made is bind him with a GL_ARRAY_BUFFER with a maximum size equivalent to all the information that may contain, leaving it empty, This is Right?
    If you're talking about the buffer object which will contain the TF output, yes. You just need to allocate it (glBufferData). You don't care what it contains as it'll be overwritten.

    1) I must use glBindBufferBase() for set each Stream in to a unique Buffer? I do not need to indicate how much space has each one?
    Or glBindBufferRange(), yes. See Buffer Binding on the Transform Feedback wiki page.

    glBindBufferBase() binds the whole buffer, however big it is, for TF output. It is expected that you've already allocated storage to it (e.g. by calling glBufferData with it bound to a buffer bind point.


    2 This includes using glMultiDrawElementsIndirectCount() from ARB_indirect_parameters?, when you says "(on top of the "instanceCount" members) in the indirect draw call buffer(s)" this means that I have to bind GL_INDIRECT_BUFFER with Tranform Feedback Object too?
    I don't understand what you're asking here.

    Separate in your mind what's required for the transform feedback pass, and then what's required for issuing an indirect draw call. You run TF first. That gives you a list of instances in each stream, and a number of instances written to each stream. ...THEN... You're going to issue an indirect draw call (or calls) that actually tell the GPU to draw with those instance lists.

    All I was trying to say is it's up to you how you communicate the number of instances written to a stream from the TF output pass -TO- the draw call parameters used by the indirect draw call. There are several possible ways. It's up to you which way you go!

    3) How I can made the output counts on geometry step to use with GL_INDIRECT_BUFFER?
    Don't think in terms of buffer binding points. Those are just like hooks that you can hang buffer objects on if/when needed. Think in terms of your buffer objects and the contents that they have.

    The buffer object bound to the GL_INDIRECT_BUFFER contains draw call parameters. These are the same parameters you'd provide in your CPU function call to a non-indirect draw call like (for instance) glDrawArraysInstanced(). To see exactly what the format is for glDrawArraysIndirect(), see the man page and look at the DrawArraysIndirectCommand struct. See the "primCount" member? That's the number of instances. You need to use some method (such as one of those described above) to copy the number of instances written to a stream in the TF output pass into that "primCount" member. Once you get it in there, then you can bind that buffer object to the GL_INDIRECT_BUFFER and issue your indirect draw call. Does that make sense?

    4) I canīt find examples codes / or exercises from 4.4Core about Transform Feedback, as a way to learn, would it be possible share some code that you have?
    I don't have time to look through a lot of code, but if you post code snippets here with specific questions, I'm sure folks here will be able to help you clear up any confusion you might have. Before you do though, I would definitely read that Transform Feedback wiki page as well as the wiki section on Indirect rendering. If something is confusing, just ask!

  3. #13
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    10
    OK, I've started from the simplest to make sure everything goes well but I've already had problems that should not be going step by step using wiki/Transform_Feedback + glspec46.pdf 13.3.1 Transform Feedback Objects.

    Forgetting temporarily my goal of instance LOD Culling, I thought a simple enough objective : using a VBO that only contain one VEC4 positions attribute, and use transform feedback to divide it in two output streams and finally using glDrawTransformFeedbackStream() to render streams as a points.

    Code :
     
    const char* varyings[] = { "POS0", "POS1" };                                               // <- TWO OUTPUT STREAMS
    glTransformFeedbackVaryings(idProgram, 2, varyings, GL_SEPARATE_ATTRIBS);                  //<- SEPARATE MODE TO GET OUTPUTS INTO SEPARATE BUFFERS 
    glLinkProgram(idProgram);
     
    //
     
    glGenBuffers(1, &BUFFER0);
    glBindBuffer(GL_ARRAY_BUFFER, BUFFER0);                                                    // <- FIRST BUFFER OUTPUT
    glBufferData(GL_ARRAY_BUFFER, max_size_data, 0, GL_STREAM_DRAW);
     
    glGenBuffers(1, &BUFFER1);
    glBindBuffer(GL_ARRAY_BUFFER, BUFFER1);                                                    // <- SECOND BUFFER OUTPUT
    glBufferData(GL_ARRAY_BUFFER, max_size_data, 0, GL_STREAM_DRAW);
     
     
    glGenTransformFeedbacks(1, &feedbackObject);
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, feedbackObject);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, BUFFER0);                                //
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, BUFFER1);                                // <- BIND BUFFERS 0 and 1
     
     
    // AFTER BIND BUFFER INPUT (that contain VBO VEC4 positions)
    glEnable(GL_RASTERIZER_DISCARD);
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, feedbackObject);
    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, countPositions);
    glEndTransformFeedback();
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
    glDisable(GL_RASTERIZER_DISCARD);
     
     
    // NOW, AFTER BIND BUFFER0 TO RENDER IT AS A STREAM 0
    glDrawTransformFeedbackStream(GL_POINTS, feedbackObject, 0);
    Code :
    layout(points) in;
    layout(points, max_vertices = 1) out;
     
    layout(stream=0) out vec4 POS0;
    layout(stream=1) out vec4 POS1;
    void main()
    {  
        if( gs_in[0].POS.x < 50.0) {                   // <- TO OBTAIN HALF IN TO EACH STREAM
                    POS0 = gs_in[0].POS;
                    EmitStreamVertex(0);
                    EndStreamPrimitive(0);
         }else {
                    POS1 = gs_in[0].POS;
                    EmitStreamVertex(1);
                    EndStreamPrimitive(1);
         }
    }

    Interestingly, this code does work with ONLY one of streams if I made this changes :

    glTransformFeedbackVaryings(idProgram, 1, varyings, GL_SEPARATE_ATTRIBS);

    Obviously I am indicate only an single exit here, but its works, only half of positions are rendered as points. I've spent all night reviewing the documentation before putting this here.
    What am I missing so that when I indicate 2 incices into set Varyings it donīt breaks?

  4. #14
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,478
    In terms of getting you a TF geometry shader/program that does successfully output to multiple streams, try this:


    A few differences between my code and yours: 1) Using INTERLEAVED instead of SEPARATE, and 2) using "gl_NextBuffer" in the glTransformFeedbackVaryings() list to explicitly designate streams.

    To your above code. Here, before the glDrawArrays:

    Code cpp:
    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, countPositions);
    glEndTransformFeedback();

    you didn't show binding a buffer to GL_ARRAY_BUFFER (but you probably did based on the comment above this section) and didn't show setting up your vertex attribute pointers and enables (glVertexAttribPointer / gl{Enable,Disable}VertexAttribArray). I realize you are just showing an excerpt above so you may have this in your actual source code. If not, add this.

    You also didn't show binding your TF program (glUseProgram), but you almost certainly have that in your actual code since you've seen this working in some cases.
    Last edited by Dark Photon; 09-19-2018 at 05:20 AM.

  5. #15
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    10
    Quote Originally Posted by Dark Photon View Post
    In terms of getting you a TF geometry shader/program that does successfully output to multiple streams, try this:

    I am using a GTX1080Ti, I set/get max_stream_outputs. I think it's relevant.


    Quote Originally Posted by Dark Photon View Post
    A few differences between my code and yours: 1) Using INTERLEAVED instead of SEPARATE, and 2) using "gl_NextBuffer" in the glTransformFeedbackVaryings() list to explicitly designate streams.

    you didn't show binding a buffer to GL_ARRAY_BUFFER (but you probably did based on the comment above this section) and didn't show setting up your vertex attribute pointers and enables (glVertexAttribPointer / gl{Enable,Disable}VertexAttribArray). I realize you are just showing an excerpt above so you may have this in your actual source code. If not, add this.

    You also didn't show binding your TF program (glUseProgram), but you almost certainly have that in your actual code since you've seen this working in some cases.
    I made the changes and it still does not work, only I can draw stream 0 (the half of all points) but when i am trying stream 1 I don't get any in screen. I'm confused anyway, why could not I use separate mode for this example?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •