Wie übergebe ich ein Java-Objekt an meinen OpenCL-Kernel?Java

Java-Forum
Anonymous
 Wie übergebe ich ein Java-Objekt an meinen OpenCL-Kernel?

Post by Anonymous »

Ich entwickle einen Java RayTracer mit OpenCL. Ich verwende derzeit JOCL, um auf die API zuzugreifen. Jetzt versuche ich, den Benutzer mit der Kamera interagieren zu lassen, und mein Plan bestand darin, eine Kamera zu erstellen, die global für den Kernel ist, und wenn der Benutzer damit interagiert, würde der Host die Kamerawerte aktualisieren und diese senden neue Werte für den Kernel. Aber es fällt mir schwer, dies umzusetzen.
Unten ist meine Implementierung der Kamera aufgeführt, sowohl in Java als auch in C. Ich habe versucht, die Werte abzugleichen, um Probleme mit der Speicherausrichtung zu vermeiden:
public class Camera {
public float aspect_ratio;
public int image_width;
public int image_height;
public float view_fov;
}

typedef struct {
float aspect_ratio;
int image_width;
int image_height;
float view_fov;
} Camera;

Die Methode zum Konvertieren der Kamera in einen Puffer, der ihre Attribute enthält:
public ByteBuffer toByteBuffer(int bufferSize) {
ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize);
buffer.putFloat(aspect_ratio);
buffer.putInt(image_width);
buffer.putInt(image_height);
buffer.putFloat(view_fov);
buffer.flip();
return buffer;
}

So erstelle ich den Puffer und sende ihn an den Kernel:
int cameraBufferSize = camera.getCameraSize();
ByteBuffer cameraBuffer = camera.toByteBuffer(cameraBufferSize);
cl_mem cameraMem = clCreateBuffer(hostManager.getContext(), CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, cameraBuffer.capacity(), Pointer.to(cameraBuffer), null);

long[] globalWorkSize = new long[2];
globalWorkSize[0] = width;
globalWorkSize[1] = height;

clSetKernelArg(hostManager.getKernel(), 0, Sizeof.cl_mem, Pointer.to(outputImageMem));
cL.clSetKernelArg(hostManager.getKernel(), 1, Sizeof.cl_mem, Pointer.to(cameraMem));
clEnqueueNDRangeKernel(hostManager.getCommandQueue(), hostManager.getKernel(), 2, null, globalWorkSize, null, 0, null, null);


Hier ist mein Kernel-Code:
__kernel void render_kernel(__global uint* output, __global Camera* camera) {
printf("aspect ratio: %f\n", camera->aspect_ratio);
printf("image width: %d\n", camera->image_width);
printf("image height: %d\n", camera->image_height);
printf("view_fov: %f\n", camera->view_fov);
}

Ich habe sogar clEnqueueReadBuffer() verwendet, um den Puffer zu lesen, nachdem ich ihn an den Kernel gesendet hatte, und die Werte schienen auf der Hostseite korrekt zu sein.
Also , für eine Kamera, die mit den folgenden Attributen initialisiert wurde:
Camera camera = new Camera(16.0 / 9.0, 800, 450, 90.0);
Bei der Ausführung gibt der Kernel die folgende Ausgabe aus:
aspect ratio: 0.000273 //expected aspect ratio -> 1.7777
image width: 327680 //expected width -> 800
image height: -805175296 //expected height -> 450
view_fov: 0.000000 //expected view_fov -> 90

Gibt es also ein Problem damit, wie ich den Puffer erstelle und sende, oder hängt es mit der Kernel-Seite zusammen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post