std::set<cl_image_format> supported_formats(const context &ctx, cl_mem_object_type type) { std::set<cl_image_format> s; pipe_texture_target target = translate_target(type); unsigned bindings = (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_COMPUTE_RESOURCE | PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE); for (auto f : formats) { if (all_of([=](const device &dev) { return dev.pipe->is_format_supported( dev.pipe, f.second, target, 1, bindings); }, ctx.devices())) s.insert(f.first); } return s; }
BOOL WINAPI wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) { HDC prevDrawable = stw_get_current_dc(); HDC prevReadable = stw_get_current_read_dc(); HDC dc; struct stw_context *curctx = stw_current_context(); struct stw_framebuffer *fb; GLenum texFormat, srcBuffer, target; boolean retVal; int pixelFormatSave; /* * Implementation notes: * Ideally, we'd implement this function with the * st_context_iface::teximage() function which replaces a specific * texture image with a different resource (the pbuffer). * The main problem however, is the pbuffer image is upside down relative * to the texture image. * Window system drawing surfaces (windows & pbuffers) are "top to bottom" * while OpenGL texture images are "bottom to top". One possible solution * to this is to invert rendering to pbuffers (as we do for renderbuffers) * but that could lead to other issues (and would require extensive * testing). * * The simple alternative is to use a copy-based approach which copies the * pbuffer image into the texture via glCopyTex[Sub]Image. That's what * we do here. */ if (!curctx) { debug_printf("No rendering context in wglBindTexImageARB()\n"); SetLastError(ERROR_INVALID_OPERATION); return FALSE; } fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer); if (!fb) { debug_printf("Invalid pbuffer handle in wglBindTexImageARB()\n"); SetLastError(ERROR_INVALID_HANDLE); return FALSE; } srcBuffer = translate_ibuffer(iBuffer); if (srcBuffer == GL_NONE) { debug_printf("Invalid buffer 0x%x in wglBindTexImageARB()\n", iBuffer); SetLastError(ERROR_INVALID_DATA); return FALSE; } target = translate_target(fb->textureTarget); if (target == GL_NONE) { debug_printf("no texture target in wglBindTexImageARB()\n"); return FALSE; } texFormat = translate_texture_format(fb->textureFormat); if (texFormat == GL_NONE) { debug_printf("no texture format in wglBindTexImageARB()\n"); return FALSE; } /* * Bind the pbuffer surface so we can read/copy from it. * * Before we can call stw_make_current() we have to temporarily * change the pbuffer's pixel format to match the context to avoid * an error condition. After the stw_make_current() we restore the * buffer's pixel format. */ pixelFormatSave = fb->iPixelFormat; fb->iPixelFormat = curctx->iPixelFormat; dc = wglGetPbufferDCARB(hPbuffer); retVal = stw_make_current(dc, dc, curctx->dhglrc); fb->iPixelFormat = pixelFormatSave; if (!retVal) { debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n"); wglReleasePbufferDCARB(hPbuffer, dc); return FALSE; } st_copy_framebuffer_to_texture(srcBuffer, fb->width, fb->height, target, fb->textureLevel, fb->textureFace, texFormat); /* rebind previous drawing surface */ retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc); if (!retVal) { debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n"); } wglReleasePbufferDCARB(hPbuffer, dc); return retVal; }