Can one invoke a non-root RenderScript kernel using rsForEach
?
There are many examples of using rsForEach
to call the root kernel from within an invokable RenderScript function:
- Documentation for Androids Renderscript advanced rsForEach call
- How to write a convolution multiplication in Android Renderscript?
- Passing Array to rsForEach in Renderscript Compute
These bind the script itself to a variable in the RenderScript context, then invoke the root kernel from within RenderScript. For example, in the Activity
class:
...
mScript = new ScriptC_gradient(mRS);
// bind Allocations and mScript to variables in the RenderScript context:
mScript.set_gIn(mImageAllocation);
mScript.set_gOut(mGradientAllocation);
mScript.set_gScript(mScript);
// invoke gradient function:
mScript.invoke_gradient();
...
And in gradient.rs
:
#pragma version(1)
#pragma rs java_package_name(com.example.android.rs.hellocompute)
rs_allocation gOut;
rs_allocation gIn;
rs_script gScript;
void gradient() {
rsForEach(gScript, gIn, gOut);
}
void root(const uchar4 *v_in, uchar4 *v_out, ...
But if I have another kernel gray
could I invoke it after root
, inside gradient
?
// I thought it would look like this:
void gradient() {
rsForEach(gScript, gIn, gOut);
rsForEach(gScript, gIn, gOut, NULL, NULL, gExportForEachIdx_gray);
}
// Or:
void gradient() {
rsForEach(gScript, gIn, gOut);
rsSetMainKernel(&gScript, "gray");
rsForEach(gScript, gIn, gOut);
}
But the documentation for rsForEach
seems to indicate that it doesn't support anything like this. Perhaps it can be accomplished by setting something in a rs_script_call_t
, but the doc is rather terse about that type: (Retrieved 20 September 2013)
typedef struct rs_script_call rs_script_call_t**
Structure to provide extra information to a rsForEach call. Primarly used to restrict the call to a subset of cells in the allocation.
This question is mostly out of curiosity- I expect the preferred method is to call them from Java:
...
mScript = new ScriptC_gradient(mRS);
// bind Allocations and mScript to variables in the RenderScript context:
mScript.forEach_root(mImageAllocation, mGradientAllocation);
mScript.forEach_gray(mGradientAllocation, mGrayGradientAllocation);
...
These seem to be synchronized. If one defines root
and gray
as follows:
void root(...) { rsDebug("root", 0,0); }
void gray(...) { rsDebug("gray", 1,1); }
then calling forEach_root
then forEach_gray
causes "root, {0,0}" to be logged NxM times before it starts logging "gray, {1,1}" - I haven't found documentation that guarantees that, though. Anybody know where that is?
Unfortunately we don't currrently have a way to invoke a non-root RenderScript kernel using rsForEach() from the script. You will have to call into it from Java directly. You could also put the second kernel in another Script as root() and then bind that rs_script as well (e.g. you can have gScriptGradient and gScriptGray and execute them sequentially from a single invoke in your primary Script).
I initially missed your second question about synchronization between parallel kernels. They are indeed ordered. Although kernels are launched asynchronously, the second kernel will not run until the first kernel is complete.
来源:https://stackoverflow.com/questions/18924176/can-one-use-renderscripts-rsforeach-on-a-non-root-kernel