0
後續這個問題Problems with OpenCL/OpenGL Texture interop/windows:的OpenCL/OpenGL的紋理互操作:調整OpenGL紋理
我們:
- 渲染到FBO,附帶作爲COLOR_ATTACHMENT0紋理,這是
inTex
- OpenCL中可分離downscaler,使用
inTex
,通過tempTex
現在出現了一個新問題,因爲這是一個編輯器實現。如果inTex
的大小發生變化或者outTex
的大小發生變化,則首先使用glTexImage2d
調整OpenGL紋理的大小。然後釋放三個內核對象,最後使用clReleaseMemObj(XTex)
發佈所有三種紋理的對象。最後一步簡單地使用與初始化時相同的代碼重新創建所有必需的對象,並繼續循環。
在使用clCreateFromGLTexture2D
重新創建那些紋理的cl_mem對象時,我收到CL_OUT_OF_RESOURCES
。相應地,縮減不再被執行,因爲設置紋理內核參數產生CL_INVALID_MEM_OBJECT
。
也許有些僞代碼有助於理解這個問題:
// OBJECTS //
////////////
cl_kernel k_x, k_y, k_clear;
cl_mem textureObjects[3];
int src_width, src_height, dst_width, dst_height;
size_t rngClr[3], offsClr[3], range_x[3], range_y[3];
float clrCol[4]
// MAIN ENTRY POINT //
/////////////////////
if ((fbo) && calculate())
{
glFinish();
if (CL_recreate) recreateCLstuff();
CLmgr->acquireGLObjects(3, textureObjects);
CLmgr->callKernel(k_clear, rngClr, offsClr, "clear");
CLmgr->setSimpleKernelArg(k_x, 3, 8, &convertXY, "horizontal::convert");
CLmgr->setSimpleKernelArg(k_x, 4, 16, &offsets_X, "horizontal::offset");
CLmgr->callKernel(k_x, range_x, "horizontal downsample");
CLmgr->setSimpleKernelArg(k_y, 3, 8, &convertXY.m128_f32[ 2 ], "vertical::convert");
CLmgr->setSimpleKernelArg(k_y, 4, 16, &offsets_Y, "vertical::offset");
CLmgr->callKernel(k_y, range_y, "vertical downsample");
CLmgr->releaseGLObjects(3, textureObjects);
clFinish();
}
bool calculate()
{
// check if a resize of the "inTex" happened or a resize of
// "outTex" or "tempTex" is necessary
int srcw, srch, dstw, dsth;
// acquire above values
if ((srcw != src_width) || (srch != src_height) || (dstw != dst_width) || (dsth != dst_height))
{
CL_recreate = true;
// rebuild temporary texture
if ((dst_width != dstw) || (src_height != srch))
resizeTemporaryOpenGLTexture();
// rebuild target texture
if ((dst_width != dstw) || (dst_height != dsth))
resizeOutputOpenGLTexture();
// finally copy new values to the non-temporary objects
}
// produce all necessary parameters:
// - ranges (rngClr, offsClr, range_x, range_y)
// - convertXY
// - offsets_X
// - offsets_Y
}
void recreateCLstuff()
{
releaseCLstuff();
cerr << name() << ": recreating CL-stuff...\n";
k_x = CLmgr->newKernelInstance(className(), "separable");
k_y = CLmgr->newKernelInstance(className(), "separable");
k_clearEmpty = CLmgr->newKernelInstance(className(), "clearEmpty");
k_clear = CLmgr->newKernelInstance(className(), "clear");
// [...]
textureObjects[ 0 ] = CLmgr->createTexture(sourceTexID, WI_CL_TEXTURE_USE::sourceTexture, "source FBO texture");
CLmgr->setMemKernelArg(k_x, 0, textureObjects[ 0 ], "horizontal::src");
textureObjects[ 1 ] = CLmgr->createTexture(tempTexID, WI_CL_TEXTURE_USE::tempTexture, "separable downscaler buffer");
CLmgr->setMemKernelArg(k_x, 1, textureObjects[ 1 ], "horizontal::dst");
CLmgr->setMemKernelArg(k_y, 0, textureObjects[ 1 ], "vertical::src");
textureObjects[ 2 ] = CLmgr->createTexture(textureID, WI_CL_TEXTURE_USE::targetTexture, "WI_CLtexture target");
CLmgr->setMemKernelArg(k_y, 1, textureObjects[ 2 ], "vertical::dst");
CLmgr->setMemKernelArg(k_clear, 1, textureObjects[ 2 ], "clear::dst");
CLmgr->setSimpleKernelArg(k_clear, 0, 16, clrCol, "clear::clearColor");
CL_recreate = false;
}
void releaseCLstuff()
{
cerr << name() << ": releasing CL stuff...\n";
cl_int err;
#define releaseKernel(obj) if (obj) if (err = clReleaseKernel(obj)) cerr << "release kernel object \""##obj##"\" failed! (" << clErrorString(err) << ")\n"
releaseKernel(k_x);
releaseKernel(k_y);
releaseKernel(k_clear);
for (int i = 0; i < 3; ++i)
{
if (textureObjects[ i ])
if (err = clReleaseMemObject(textureObjects[ i ]))
cerr << "release texture object #" << i << " failed! (" << clErrorString(err) << ")\n";
else
textureObjects[ i ] = nullptr;
}
}