2017-09-26 7 views
4

J'ai un shader opencl qui tente d'écrire une couleur sur une texture, mais pour une raison quelconque, seul le canal rouge est appliqué à la texture, le reste est ignoré. Non seulement cela, mais cette valeur de canal rouge est copiée sur tous les autres canaux, ce qui me donne du blanc avec une certaine transparence. Quelqu'un sait-il pourquoi cela arriverait? Am programmation en utilisant Xcode sur un Mac, (OpenCL 1.2). La texture est d'abord créée en utilisant OpenGL et partagée avec OpenCL.Pourquoi OpenCL shader ignore-t-il les canaux vert, bleu et alpha lors de l'écriture dans OpenGL Texture?

Voilà comment je déclare la texture que j'écris en utilisant OpenGL:

void TextureManager::createTexture3D(TextureManager::TexturesInfo 
*texturesInfo, GLuint textureName) 
{ 
    glError(); 
    glBindTexture(GL_TEXTURE_3D, texturesInfo->tex[textureName]); 
    glError(); 
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glError(); 
    GLint level = 0, border = 0; 

    GLint rgbType = GL_RGBA32F; 
    GLint format = GL_RGBA; 
    glTexImage3D(GL_TEXTURE_3D, level, rgbType, LPV::LPV_WIDTH, LPV::LPV_HEIGHT, LPV::LPV_DEPTH, border, format, GL_FLOAT, NULL); 
    glError(); 
} 

Ceci est le code qui crée la ressource partagée avec OpenCL:

GLint error; 
accume_buffer = clCreateFromGLTexture(context,CL_MEM_READ_ONLY, GL_TEXTURE_3D, 0, _lpvTextures.accumeBuffer, &error); 
assert(error == CL_SUCCESS); 
accume_buffer2 = clCreateFromGLTexture(context,CL_MEM_WRITE_ONLY, GL_TEXTURE_3D, 0, _lpvTextures.accumeBuffer2, &error); 
assert(error == CL_SUCCESS); 

Ceci est le code qui exécute le shader OpenCL:

void LPV::runComputeShader(){ 

glFlush(); 
glFinish(); 
GLint error = 0; 
cl_event opengl_get_completion; 
error =clEnqueueAcquireGLObjects(command_queue, 1, &accume_buffer, 0,0,&opengl_get_completion); 
clWaitForEvents(1, &opengl_get_completion); 
clReleaseEvent(opengl_get_completion); 
assert(error == CL_SUCCESS); 
error =clEnqueueAcquireGLObjects(command_queue, 1, &accume_buffer2, 0,0,0); 
assert(error == CL_SUCCESS); 

error |= clSetKernelArg(computeKernel, 0, sizeof(cl_image), &accume_buffer); 
assert(error == CL_SUCCESS); 
error |= clSetKernelArg(computeKernel, 1, sizeof(cl_image), (void*)&accume_buffer2); 
assert(error == CL_SUCCESS); 


GLuint dimensions = 3; 
size_t globalWorkSize[] = {LPV::LPV_WIDTH, LPV_HEIGHT, LPV_DEPTH }; 
size_t localWorkSize[] = { 1, 1, 1}; 

cl_event kernel_completion; 
error = clEnqueueNDRangeKernel(command_queue, computeKernel, dimensions, NULL, globalWorkSize, nullptr, 0, NULL, &kernel_completion); 
assert(error == CL_SUCCESS); 
error = clWaitForEvents(1, &kernel_completion); 
error |= clReleaseEvent(kernel_completion); 
assert(error == CL_SUCCESS); 


error = clEnqueueReleaseGLObjects(command_queue, 1, &accume_buffer, 0, 0, 0); 
assert(error == CL_SUCCESS); 
error = clEnqueueReleaseGLObjects(command_queue, 1, &accume_buffer2, 0, 0, 0); 
assert(error == CL_SUCCESS); 

clFlush(command_queue); 
clFinish(command_queue); 


} 

Et enfin, c'est le shader OpenCL lui-même:

#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable 

const sampler_t lpvSampler = CLK_NORMALIZED_COORDS_FALSE | 
CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; 


kernel void propagate_lpv 
        (
         read_only image3d_t src_buffer, 
         write_only image3d_t dest_buffer 
        ) 
{ 
    int4 coord; 
    coord.x = (int)get_global_id(0); 
    coord.y = (int)get_global_id(1); 
    coord.z = (int)get_global_id(2); 
    coord.w = 1; 

float4 color = float4(1.0f, 0.0f, 0.0f, 1.0f); 
write_imagef(dest_buffer, coord, color); 


} 

Est-ce que quelqu'un a la moindre idée de ce qui se passerait? Merci

Répondre

2

Le problème était que j'utilisais la mauvaise syntaxe. Malheureusement OpenCL et GLSL ne semblent pas suivre la même syntaxe qui était ma supposition. La syntaxe correcte selon le guide de programmation OpenCL est la suivante:

(float4)(float, float, float, float) 
(float4)(float2, float, float) 
(float4)(float, float2, float) 
(float4)(float, float, float2) 
(float4)(float2, float2) 
(float4)(float3, float) 
(float4)(float, float3) 
(float4)(float) 

afin de changer ma ligne:

float4 color = float4(1.0f, 0.0f, 0.0f, 1.0f); 

à:

float4 color = (float4)(1.0f, 0.0f, 0.0f, 1.0f); 

me donne une texture rouge, ce qui est ce que je attendre.