cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

Inco
Journeyman III

how can i use read/write buffer?

How can I write kernel with the Brook+, which makes the buffer to read and write?

How can I write kernel with the Brook+, which makes the buffer to read and write?

I have: image(704x576) and logical grid(22x18(edge=32)) on this image - one grid cell goups 32x32 pixel under it.

I need to proccess image, and calc (for example) number of red pixels (color.R > 200, for example) in every cell, BUT in this kernel i want mark all pixel to green (color.G = 255);

Show the code:

brook::Stream<int> img(...);  // 704x576
brook::Stream<int> res(...);  // 704x576
brook::Stream<int> mask(...);    // edge=32 -> (704/edge)x(576/edge) -> 22x18
...   
Kernel1(img, mask, res);    // sart thread for every pixel

kernel void Kernel1(int frame[][], int mask[][], out int outputFrame<>
{       
    int xMask = vPos.x / edge;   
    int yMask = vPos.y / edge;   
    int2 maskPos = int2(xMask, yMask);  // index of grid cell when current pixel is located

    int color = frame[instance().xy];    // current pixel
    int red = color & 0xFF;                // get r-channel
    if (red > 200)
        mask[maskPos]++;
   
    outputFrame = color | 0x00FF0000;   
}

 

can i make it work?

0 Likes
2 Replies
gaurav_garg
Adept I

You seems to be reading and writing from the same stream. That is not currently possible in Brook+. To make it work, you need to use a scatter and a regular output stream. That again is a limitation in Brook+. But, you can try dividing your kernel in two parts  -

kernel void Kernel1(int frame<>, out int mask[][])
{
    int2 vPos = instance().xy;      
    int xMask = vPos.x / edge;  
    int yMask = vPos.y / edge;  
    int2 maskPos = int2(xMask, yMask);  // index of grid cell when current pixel is located

    int color = frame;    // current pixel
    int red = color & 0xFF;                // get r-channel
    if (red > 200)
        mask[maskPos]++;
}

and

kernel void Kernel2(int frame<>, out int outputFrame<>
{
    outputFrame = frame | 0x00FF0000;  
}

Also you need to set execution domain on Kernel1 from host side code-

// Set domain offset
Kernel1.domainOffset(uint4(0, 0, 0, 0));
Kernel1.domainSize(uint4(704, 576, 1, 1));

// call kernel
Kernel1(img, mask);

 

But, I think its very unlikely that this code will work as underlying hardware has some limitations in size and domain of execution for scatter use (Both has to be 64-aligned). If you can resolve these alignment constraints, it should work.

0 Likes

Very grateful for the answer!
I just started to learn "ATI Strem" and have a lot of questions! 😃

May i ask another question:
  When i reading the documentation, i don't understood the logic of how Brook + understands, how much flows to start? According size of "out" parameters, or size of "<>" streem parameters? jr some another logic?

0 Likes