2016-08-19 3 views
1

OpenCL에서 재귀 적 레이 트레이싱을 구현하는 프로그램을 개발 중입니다. 커널을 실행하려면 시스템과 Nvidia GeForce 그래픽 카드가 통합 된 인텔 옵션 장치가 필요합니다.OpenCL에서 clEnqueueMapBuffer와 관련된 문제

첫 번째 장치로 프로젝트를 실행할 때 문제가 없습니다. 그것은 올바르게 실행되고 알고리즘의 결과를 잘 보여줍니다.

그러나 Nvidia 장치로 실행하려고하면 동기 버퍼 맵이있는 콜백 함수가 충돌합니다. clEnqueueMapBuffer에

clEnqueueNDRangeKernel( queue, kernel, 1, NULL, &global_work_size, NULL, 0, NULL, NULL); 

// 7. Look at the results via synchronous buffer map. 
cl_float4 *ptr = (cl_float4 *) clEnqueueMapBuffer(queue, buffer, CL_TRUE, CL_MAP_READ, 0, kWidth * kHeight * sizeof(cl_float4), 0, NULL, NULL, NULL); 
cl_float *viewTransformPtr = (cl_float *) clEnqueueMapBuffer(queue, viewTransform, CL_TRUE, CL_MAP_WRITE, 0, 16 * sizeof(cl_float), 0, NULL, NULL, NULL); 
cl_float *worldTransformsPtr = (cl_float *) clEnqueueMapBuffer(queue, worldTransforms, CL_TRUE, CL_MAP_WRITE, 0, 16 * sizeof(cl_float), 0, NULL, NULL, NULL); 

memcpy(viewTransformPtr, viewMatrix, sizeof(float)*16); 
memcpy(worldTransformsPtr, sphereTransforms, sizeof(float)*16); 

clEnqueueUnmapMemObject(queue, viewTransform, viewTransformPtr, 0, 0, 0); 
clEnqueueUnmapMemObject(queue, worldTransforms, worldTransformsPtr, 0, 0, 0); 

unsigned char* pixels = new unsigned char[kWidth*kHeight*4]; 
for(int i=0; i < kWidth * kHeight; i++){ 
    pixels[i*4] = ptr[i].s[0]*255; 
    pixels[i*4+1] = ptr[i].s[1]*255; 
    pixels[i*4+2] = ptr[i].s[2]*255; 
    pixels[i*4+3] = 1; 
} 

glBindTexture(GL_TEXTURE_2D, 1); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexImage2D(GL_TEXTURE_2D, 0, 4, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 
delete [] pixels; 

두 마지막 호출이 오류 -5 CL_OUT_OF_RESOURCES 일치 반환하지만 버퍼의 크기가 올바른지 생각 :

가 충돌 코드의 일부는 다음과 같습니다.

답변

0

CL 스펙에 따르면 콜백에서 CL 블로킹 호출을 호출하는 것은 정의되지 않습니다. 코드가 맞을 수도 있지만 콜백에서 사용할 수는 없습니다. 통합 메모리가있는 Intel 플랫폼에서 맵은 아무 작업도 수행하지 않으므로 실패하지 않습니다.

CL spec: clSetEventCallbacks

, 에의 OpenCL API 호출, 상황 또는 명령 대기열을 작성 고가의 시스템 루틴을 호출이나 콜백이 정의되지에서 아래 에서 다음 목록을 OpenCL을 조작의 블록의 동작

.

clFinish 
clWaitForEvents 
blocking calls to clEnqueueReadBuffer, clEnqueueReadBufferRect, clEnqueueWriteBuffer, and clEnqueueWriteBufferRect 
blocking calls to clEnqueueReadImage and clEnqueueWriteImage 
blocking calls to clEnqueueMapBuffer and clEnqueueMapImage 
blocking calls to clBuildProgram 

응용 프로그램이 콜백에서 리터 인도 표준시 위의 에서 루틴의 완료를 기다려야하는 경우, 함수의 비 차단 양식을 사용하여 작업을 수행하는 데에 완료 콜백을 지정하십시오 남은 작품은 입니다. 콜백 (또는 다른 코드)이 명령 대기열에 명령을 대기열에 추가하면 명령이 대기열이 플러시 될 때까지 실행을 시작할 필요가 없습니다. 표준 사용에서는 대기열을 암시 적으로 플러시하여대기열 호출을 차단하면이 역할이 수행됩니다. 블로킹 호출이 콜백에서 허용되지 않기 때문에 명령 대기열에서 큐로깅하는 명령은 대기열에서 clFlush를 호출해야합니다. 그렇지 않으면 clFlush가 나중에 다른 스레드에서 호출되도록 정렬해야합니다.