23 return "GL_INVALID_ENUM";
24 case GL_INVALID_VALUE:
25 return "GL_INVALID_VALUE";
26 case GL_INVALID_OPERATION:
27 return "GL_INVALID_OPERATION";
28 case GL_INVALID_FRAMEBUFFER_OPERATION:
29 return "GL_INVALID_FRAMEBUFFER_OPERATION";
30 case GL_FRAMEBUFFER_COMPLETE:
31 return "GL_FRAMEBUFFER_COMPLETE";
32 case GL_OUT_OF_MEMORY:
33 return "GL_OUT_OF_MEMORY";
43 case GL_INVALID_VALUE:
44 case GL_INVALID_OPERATION:
45 case GL_INVALID_FRAMEBUFFER_OPERATION:
46 case GL_OUT_OF_MEMORY:
54 return [resolver](
const char* function_name) ->
void* {
55 auto resolved = resolver(function_name);
61 auto function = std::string{function_name};
62 if (
function.find(
"KHR",
function.size() - 3) != std::string::npos) {
63 auto truncated =
function.substr(0u,
function.size() - 3);
64 return resolver(truncated.c_str());
66 if (
function.find(
"EXT",
function.size() - 3) != std::string::npos) {
67 auto truncated =
function.substr(0u,
function.size() - 3);
68 return resolver(truncated.c_str());
85 auto error_fn =
reinterpret_cast<PFNGLGETERRORPROC
>(resolver(
"glGetError"));
91 #define IMPELLER_PROC(proc_ivar) \
92 if (auto fn_ptr = resolver(proc_ivar.name)) { \
93 proc_ivar.function = \
94 reinterpret_cast<decltype(proc_ivar.function)>(fn_ptr); \
95 proc_ivar.error_fn = error_fn; \
97 VALIDATION_LOG << "Could not resolve " << proc_ivar.name; \
103 description_ = std::make_unique<DescriptionGLES>(*
this);
105 if (!description_->IsValid()) {
109 if (description_->IsES()) {
117 #define IMPELLER_PROC(proc_ivar) \
118 if (auto fn_ptr = resolver(proc_ivar.name)) { \
119 proc_ivar.function = \
120 reinterpret_cast<decltype(proc_ivar.function)>(fn_ptr); \
121 proc_ivar.error_fn = error_fn; \
124 if (description_->GetGlVersion().IsAtLeast(
Version(3))) {
133 PushDebugGroupKHR.Reset();
134 PopDebugGroupKHR.Reset();
135 ObjectLabelKHR.Reset();
137 GetIntegerv(GL_MAX_LABEL_LENGTH_KHR, &debug_label_max_length_);
140 if (!description_->HasExtension(
"GL_EXT_discard_framebuffer")) {
141 DiscardFramebufferEXT.Reset();
144 if (!description_->HasExtension(
"GL_ANGLE_framebuffer_blit")) {
145 BlitFramebufferANGLE.Reset();
148 capabilities_ = std::make_shared<CapabilitiesGLES>(*
this);
161 const fml::Mapping& mapping,
162 const std::vector<Scalar>& defines)
const {
163 if (defines.empty()) {
164 const GLchar* sources[] = {
165 reinterpret_cast<const GLchar*
>(mapping.GetMapping())};
166 const GLint lengths[] = {
static_cast<GLint
>(mapping.GetSize())};
167 ShaderSource(shader, 1u, sources, lengths);
171 if (!shader_source.has_value()) {
176 const GLchar* sources[] = {
177 reinterpret_cast<const GLchar*
>(shader_source->c_str())};
178 const GLint lengths[] = {
static_cast<GLint
>(shader_source->size())};
179 ShaderSource(shader, 1u, sources, lengths);
184 const fml::Mapping& mapping,
185 const std::vector<Scalar>& defines)
const {
186 std::string shader_source = std::string{
187 reinterpret_cast<const char*
>(mapping.GetMapping()), mapping.GetSize()};
191 size_t index = shader_source.find(
'\n');
192 if (index == std::string::npos) {
197 std::stringstream ss;
199 for (
auto i = 0u; i < defines.size(); i++) {
200 ss <<
"#define SPIRV_CROSS_CONSTANT_ID_" << i <<
" " << defines[i] <<
'\n';
202 auto define_string = ss.str();
203 shader_source.insert(index + 1, define_string);
204 return shader_source;
208 return description_.get();
213 return capabilities_;
218 case GL_FRAMEBUFFER_COMPLETE:
219 return "GL_FRAMEBUFFER_COMPLETE";
220 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
221 return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
222 #if GL_ES_VERSION_2_0
223 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
224 return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
226 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
227 return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
228 case GL_FRAMEBUFFER_UNSUPPORTED:
229 return "GL_FRAMEBUFFER_UNSUPPORTED";
230 case GL_INVALID_ENUM:
231 return "GL_INVALID_ENUM";
234 return "Unknown FBO Error Status";
239 case GL_RENDERBUFFER:
240 return "GL_RENDERBUFFER";
247 return "Unknown Type";
252 GLint
type = GL_NONE;
253 gl.GetFramebufferAttachmentParameteriv(
256 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
260 if (
type != GL_NONE) {
261 GLint
object = GL_NONE;
262 gl.GetFramebufferAttachmentParameteriv(
265 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
268 std::stringstream stream;
273 return "No Attachment";
277 GLint framebuffer = GL_NONE;
278 GetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer);
279 if (framebuffer == GL_NONE) {
280 return "The default framebuffer (FBO0) was bound.";
282 if (IsFramebuffer(framebuffer) == GL_FALSE) {
283 return SPrintF(
"The framebuffer binding (%d) was not a valid framebuffer.",
287 GLenum status = CheckFramebufferStatus(GL_FRAMEBUFFER);
288 std::stringstream stream;
290 << ((framebuffer == GL_NONE) ?
"(Default)"
291 : std::to_string(framebuffer))
294 stream <<
"Framebuffer is complete." << std::endl;
296 stream <<
"Framebuffer is incomplete." << std::endl;
298 stream <<
"Description: " << std::endl;
299 stream <<
"Color Attachment: "
302 stream <<
"Depth Attachment: "
305 stream <<
"Stencil Attachment: "
312 GLint framebuffer = GL_NONE;
313 GetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer);
314 if (IsFramebuffer(framebuffer) == GL_FALSE) {
318 GLenum status = CheckFramebufferStatus(GL_FRAMEBUFFER);
319 return status == GL_FRAMEBUFFER_COMPLETE;
327 return GL_BUFFER_KHR;
329 return GL_PROGRAM_KHR;
331 return GL_SHADER_KHR;
333 return GL_RENDERBUFFER;
335 return GL_FRAMEBUFFER;
337 return GL_SYNC_FENCE;
347 return gl.IsTexture(name);
349 return gl.IsBuffer(name);
351 return gl.IsProgram(name);
353 return gl.IsShader(name);
355 return gl.IsRenderbuffer(name);
357 return gl.IsFramebuffer(name);
365 if (debug_label_max_length_ <= 0) {
368 if (!ObjectLabelKHR.IsAvailable()) {
376 std::string_view label)
const {
384 const auto label_length =
385 std::min<GLsizei>(debug_label_max_length_ - 1, label.size());
386 if (!identifier.has_value()) {
389 ObjectLabelKHR(identifier.value(),
398 #ifdef IMPELLER_DEBUG
399 if (debug_label_max_length_ <= 0) {
404 const auto label_length =
405 std::min<GLsizei>(debug_label_max_length_ - 1, label.size());
406 PushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR,
407 static_cast<GLuint
>(
id.
id),
415 #ifdef IMPELLER_DEBUG
416 if (debug_label_max_length_ <= 0) {
426 GetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
431 length = std::min<GLint>(length, 1024);
436 GetProgramInfoLog(program,
439 reinterpret_cast<GLchar*
>(allocation.
GetBuffer())
444 return std::string{
reinterpret_cast<const char*
>(allocation.
GetBuffer()),
445 static_cast<size_t>(length)};
Describes an allocation on the heap.
uint8_t * GetBuffer() const
Gets the pointer to the start of the allocation.
bool Truncate(Bytes length, bool npot=true)
Resize the underlying allocation to at least given number of bytes.
FOR_EACH_IMPELLER_ES_ONLY_PROC(IMPELLER_PROC)
std::optional< std::string > ComputeShaderWithDefines(const fml::Mapping &mapping, const std::vector< Scalar > &defines) const
void PopDebugGroup() const
bool SetDebugLabel(DebugResourceType type, GLint name, std::string_view label) const
FOR_EACH_IMPELLER_GLES3_PROC(IMPELLER_PROC)
std::function< void *(const char *function_name)> Resolver
void ShaderSourceMapping(GLuint shader, const fml::Mapping &mapping, const std::vector< Scalar > &defines={}) const
Set the source for the attached [shader].
FOR_EACH_IMPELLER_DESKTOP_ONLY_PROC(IMPELLER_PROC)
std::string GetProgramInfoLogString(GLuint program) const
bool SupportsDebugLabels() const
std::string DescribeCurrentFramebuffer() const
const std::shared_ptr< const CapabilitiesGLES > & GetCapabilities() const
bool IsCurrentFramebufferComplete() const
ProcTableGLES(Resolver resolver)
FOR_EACH_IMPELLER_PROC(IMPELLER_PROC)
FOR_EACH_IMPELLER_EXT_PROC(IMPELLER_PROC)
void PushDebugGroup(const std::string &string) const
const DescriptionGLES * GetDescription() const
ProcTableGLES::Resolver WrappedResolver(const ProcTableGLES::Resolver &resolver)
static const char * AttachmentTypeString(GLint type)
bool GLErrorIsFatal(GLenum value)
std::string SPrintF(const char *format,...)
const char * GLErrorToString(GLenum value)
static const char * FramebufferStatusToString(GLenum status)
static std::optional< GLenum > ToDebugIdentifier(DebugResourceType type)
static bool ResourceIsLive(const ProcTableGLES &gl, DebugResourceType type, GLint name)
static std::string DescribeFramebufferAttachment(const ProcTableGLES &gl, GLenum attachment)
#define IMPELLER_PROC(proc_ivar)
#define IP_ENABLE_GLES_LABELING
Enable to allow GLES to push/pop labels for usage in GPU traces.