1) How can I access in forEach_root() other elements except for the current one?
In OpenCL we have pointer to the first element and then can use get_global_id(0) to get current index. But we can still access all other elements. In Renderscript, do we only have pointer to the current element?
2) How can I loop through an Allocation in forEach_root()?
I have a code that uses nested (double) loop in java. Renderscript automates the outer loop, but I can't find any information on implementing the inner loop. Below is my best effort:
void root(const float3 *v_in, float3 *v_out) {
rs_allocation alloc = rsGetAllocation(v_in);
uint32_t cnt = rsAllocationGetDimX(alloc);
*v_out = 0;
for(int i=0; i<cnt; i++)
*v_out += v_in[i];
}
But here rsGetAllocation() fails when called from forEach_root().
05-11 21:31:29.639: E/RenderScript(17032): ScriptC::ptrToAllocation, failed to find 0x5beb1a40
Just in case I add my OpenCL code that works great under Windows. I'm trying to port it to Renderscript
typedef float4 wType;
__kernel void gravity_kernel(__global wType *src,__global wType *dst)
{
int id = get_global_id(0);
int count = get_global_size(0);
double4 tmp = 0;
for(int i=0;i<count;i++) {
float4 diff = src[i] - src[id];
float sq_dist = dot(diff, diff);
float4 norm = normalize(diff);
if (sq_dist<0.5/60)
tmp += convert_double4(norm*sq_dist);
else
tmp += convert_double4(norm/sq_dist);
}
dst[id] = convert_float4(tmp);
}
You can provide data apart from your root function. In the current android version (4.2) you could do the following (It is an example from an image processing scenario):
Renderscript snippet:
#pragma version(1)
#pragma rs java_package_name(com.example.renderscripttests)
//Define global variables in your renderscript:
rs_allocation pixels;
int width;
int height;
// And access these in your root function via rsGetElementAt(pixels, px, py)
void root(uchar4 *v_out, uint32_t x, uint32_t y)
{
for(int px = 0; px < width; ++px)
for(int py = 0; py < height; ++py)
{
// unpack a color to a float4
float4 f4 = rsUnpackColor8888(*(uchar*)rsGetElementAt(pixels, px, py));
...
Java file snippet
// In your java file, create a renderscript:
RenderScript renderscript = RenderScript.create(this);
ScriptC_myscript script = new ScriptC_myscript(renderscript);
// Create Allocations for in- and output (As input the bitmap 'bitmapIn' should be used):
Allocation pixelsIn = Allocation.createFromBitmap(renderscript, bitmapIn,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
Allocation pixelsOut = Allocation.createTyped(renderscript, pixelsIn.getType());
// Set width, height and pixels in the script:
script.set_width(640);
script.set_height(480);
script.set_pixels(pixelsIn);
// Call the for each loop:
script.forEach_root(pixelsOut);
// Copy Allocation to the bitmap 'bitmapOut':
pixelsOut.copyTo(bitmapOut);
You can see, the input 'pixelsIn' is previously set and used inside the renderscript when calling the forEach_root function to calculate values for 'pixelsOut'. Also width and height are previously set.