Skip to content

Commit ae08ed2

Browse files
committed
glslang_parse_meta - no longer uses sscanf but strtod. about 3x
faster than sscanf original function
1 parent d6b974c commit ae08ed2

1 file changed

Lines changed: 161 additions & 79 deletions

File tree

gfx/drivers_shader/slang_process.cpp

Lines changed: 161 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -512,108 +512,190 @@ static bool glslang_parse_meta(const struct shader_line_buf *lines,
512512
char id[64];
513513
char desc[64];
514514
size_t i;
515+
515516
id[0] = '\0';
516517
desc[0] = '\0';
518+
517519
for (i = 0; i < lines->num_lines; i++)
518520
{
519521
const char *line = shader_line_buf_get(lines, i);
520522
if (!line)
521523
continue;
522-
if (!memcmp(line, "#pragma", sizeof("#pragma")-1))
524+
525+
if (memcmp(line, "#pragma", sizeof("#pragma") - 1))
526+
continue;
527+
528+
/* Check for shader identifier */
529+
if (!memcmp(line, "#pragma name ",
530+
sizeof("#pragma name ") - 1))
523531
{
524-
/* Check for shader identifier */
525-
if (!memcmp(line, "#pragma name ",
526-
sizeof("#pragma name ")-1))
532+
const char *str = line + (sizeof("#pragma name ") - 1);
533+
while (*str == ' ' || *str == '\t')
534+
str++;
535+
if (!meta->name.empty())
527536
{
528-
const char *str = NULL;
529-
if (!meta->name.empty())
530-
{
531-
RARCH_ERR("[Slang] Trying to declare multiple names for file.\n");
532-
return false;
533-
}
534-
str = line + (sizeof("#pragma name ")-1);
535-
while (*str == ' ')
536-
str++;
537-
meta->name = str;
537+
RARCH_ERR("[Slang] Trying to declare multiple names for file.\n");
538+
return false;
538539
}
539-
/* Check for shader parameters */
540-
else if (!memcmp(line, "#pragma parameter ",
541-
sizeof("#pragma parameter ")-1))
540+
meta->name = str;
541+
}
542+
/* Check for shader parameters */
543+
else if (!memcmp(line, "#pragma parameter ",
544+
sizeof("#pragma parameter ") - 1))
545+
{
546+
float initial, minimum, maximum, step;
547+
int fields = 0;
548+
const char *s = line + (sizeof("#pragma parameter ") - 1);
549+
size_t len = 0;
550+
char *end = NULL;
551+
552+
/* Parse id */
553+
while (*s == ' ' || *s == '\t')
554+
s++;
555+
len = 0;
556+
while (s[len] && s[len] != ' ' && s[len] != '\t')
557+
len++;
558+
if (len == 0 || len >= sizeof(id))
542559
{
543-
float initial, minimum, maximum, step;
544-
int ret = sscanf(
545-
line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
546-
id, desc, &initial, &minimum, &maximum, &step);
547-
if (ret == 5)
548-
{
549-
step = 0.1f * (maximum - minimum);
550-
ret = 6;
551-
}
552-
if (ret == 6)
560+
RARCH_ERR("[Slang] Invalid #pragma parameter line: \"%s\".\n", line);
561+
return false;
562+
}
563+
memcpy(id, s, len);
564+
id[len] = '\0';
565+
s += len;
566+
567+
/* Parse quoted description */
568+
while (*s == ' ' || *s == '\t')
569+
s++;
570+
if (*s != '"')
571+
{
572+
RARCH_ERR("[Slang] Invalid #pragma parameter line: \"%s\".\n", line);
573+
return false;
574+
}
575+
s++;
576+
len = 0;
577+
while (s[len] && s[len] != '"')
578+
len++;
579+
if (s[len] != '"' || len >= sizeof(desc))
580+
{
581+
RARCH_ERR("[Slang] Invalid #pragma parameter line: \"%s\".\n", line);
582+
return false;
583+
}
584+
memcpy(desc, s, len);
585+
desc[len] = '\0';
586+
s += len + 1;
587+
588+
/* Parse initial */
589+
while (*s == ' ' || *s == '\t')
590+
s++;
591+
initial = (float)strtod(s, &end);
592+
if (end == s)
593+
{
594+
RARCH_ERR("[Slang] Invalid #pragma parameter line: \"%s\".\n", line);
595+
return false;
596+
}
597+
s = end;
598+
599+
/* Parse minimum */
600+
while (*s == ' ' || *s == '\t')
601+
s++;
602+
minimum = (float)strtod(s, &end);
603+
if (end == s)
604+
{
605+
RARCH_ERR("[Slang] Invalid #pragma parameter line: \"%s\".\n", line);
606+
return false;
607+
}
608+
s = end;
609+
610+
/* Parse maximum */
611+
while (*s == ' ' || *s == '\t')
612+
s++;
613+
maximum = (float)strtod(s, &end);
614+
if (end == s)
615+
{
616+
RARCH_ERR("[Slang] Invalid #pragma parameter line: \"%s\".\n", line);
617+
return false;
618+
}
619+
s = end;
620+
fields = 5;
621+
622+
/* Parse step (optional) */
623+
while (*s == ' ' || *s == '\t')
624+
s++;
625+
if (*s)
626+
{
627+
step = (float)strtod(s, &end);
628+
if (end != s)
629+
fields = 6;
630+
}
631+
632+
if (fields == 5)
633+
{
634+
step = 0.1f * (maximum - minimum);
635+
fields = 6;
636+
}
637+
638+
{
639+
bool parameter_found = false;
640+
size_t parameter_index = 0;
641+
size_t j;
642+
643+
for (j = 0; j < meta->parameters.size(); j++)
553644
{
554-
bool parameter_found = false;
555-
size_t parameter_index = 0;
556-
size_t j;
557-
for (j = 0; j < meta->parameters.size(); j++)
645+
if (meta->parameters[j].id == id)
558646
{
559-
/* Note: LHS is a std:string, RHS is a C string.
560-
* (the glslang_meta stuff has to be C++) */
561-
if (meta->parameters[j].id == id)
562-
{
563-
parameter_found = true;
564-
parameter_index = j;
565-
break;
566-
}
647+
parameter_found = true;
648+
parameter_index = j;
649+
break;
567650
}
568-
/* Allow duplicate #pragma parameter, but only
569-
* if they are exactly the same. */
570-
if (parameter_found)
651+
}
652+
653+
/* Allow duplicate #pragma parameter, but only
654+
* if they are exactly the same. */
655+
if (parameter_found)
656+
{
657+
const glslang_parameter *parameter =
658+
&meta->parameters[parameter_index];
659+
if ( (parameter->desc != desc)
660+
|| (parameter->initial != initial)
661+
|| (parameter->minimum != minimum)
662+
|| (parameter->maximum != maximum)
663+
|| (parameter->step != step)
664+
)
571665
{
572-
const glslang_parameter *parameter =
573-
&meta->parameters[parameter_index];
574-
if ( (parameter->desc != desc)
575-
|| (parameter->initial != initial)
576-
|| (parameter->minimum != minimum)
577-
|| (parameter->maximum != maximum)
578-
|| (parameter->step != step)
579-
)
580-
{
581-
RARCH_ERR("[Slang] Duplicate parameters found for \"%s\", but arguments do not match.\n", id);
582-
return false;
583-
}
666+
RARCH_ERR("[Slang] Duplicate parameters"
667+
" found for \"%s\", but arguments"
668+
" do not match.\n", id);
669+
return false;
584670
}
585-
else
586-
meta->parameters.push_back({ id, desc, initial, minimum, maximum, step });
587671
}
588672
else
589-
{
590-
RARCH_ERR("[Slang] Invalid #pragma parameter line: \"%s\".\n",
591-
line);
592-
return false;
593-
}
673+
meta->parameters.push_back({
674+
id, desc, initial, minimum, maximum, step });
594675
}
595-
/* Check for framebuffer format */
596-
else if (!memcmp(line, "#pragma format ",
597-
sizeof("#pragma format ")-1))
676+
}
677+
/* Check for framebuffer format */
678+
else if (!memcmp(line, "#pragma format ",
679+
sizeof("#pragma format ") - 1))
680+
{
681+
const char *str = line + (sizeof("#pragma format ") - 1);
682+
while (*str == ' ' || *str == '\t')
683+
str++;
684+
if (meta->rt_format != SLANG_FORMAT_UNKNOWN)
598685
{
599-
const char *str = NULL;
600-
if (meta->rt_format != SLANG_FORMAT_UNKNOWN)
601-
{
602-
RARCH_ERR("[Slang] Trying to declare format multiple times for file.\n");
603-
return false;
604-
}
605-
str = line + (sizeof("#pragma format ")-1);
606-
while (*str == ' ')
607-
str++;
608-
meta->rt_format = glslang_find_format(str);
609-
if (meta->rt_format == SLANG_FORMAT_UNKNOWN)
610-
{
611-
RARCH_ERR("[Slang] Failed to find format \"%s\".\n", str);
612-
return false;
613-
}
686+
RARCH_ERR("[Slang] Trying to declare format"
687+
" multiple times for file.\n");
688+
return false;
689+
}
690+
meta->rt_format = glslang_find_format(str);
691+
if (meta->rt_format == SLANG_FORMAT_UNKNOWN)
692+
{
693+
RARCH_ERR("[Slang] Failed to find format \"%s\".\n", str);
694+
return false;
614695
}
615696
}
616697
}
698+
617699
return true;
618700
}
619701

0 commit comments

Comments
 (0)