Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structs: allow field names that look like vec4 fields in some cases #393

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/parse.fs
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,7 @@ type private ParseImpl() =

// A type block, like struct or interface blocks
let blockSpecifier prefix =

// Restriction on field names
let check ((_,l) as arg : Ast.Decl) =
for decl in l do
if decl.name.Name <> Rewriter.renameField decl.name.Name then
failwithf "Record field name '%s' is not allowed by Shader Minifier,\nbecause it looks like a vec4 field name." decl.name.Name
arg

let decls = many (declaration .>> ch ';' |>> check)
let decls = many (declaration .>> ch ';')
let name = opt ident
pipe2 name (between (ch '{') (ch '}') decls)
(fun n d ->
Expand Down
21 changes: 20 additions & 1 deletion src/renamer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ open System.Collections.Generic
open Ast
open Options.Globals

let renameField field =
if Builtin.isFieldSwizzle field then
field |> String.map (fun c -> options.canonicalFieldNames.[Builtin.swizzleIndex c])
else field

module private RenamerImpl =

// Environment for renamer
Expand Down Expand Up @@ -328,10 +333,24 @@ module private RenamerImpl =
renList env renCase cl |> ignore<Env>
env

let renStructElts (decls: Decl list) =
let allFields = Dictionary<string, string>()
for _, elts in decls do
for elt in elts do
let newName = renameField elt.name.Name
match allFields.TryGetValue(newName) with
| true, conflict ->
failwithf "Field '%s' will conflict with field '%s' after renaming: both will be named '%s'" elt.name.Name conflict newName
| _ ->
allFields.[newName] <- elt.name.Name
elt.name.Rename(newName)

// e.g. struct foo { int a; float b; }
// or uniform foo { int a; float b; }
let renTyBlock (env: Env) = function
| TypeBlock("struct", _, _) -> env
| TypeBlock("struct", _, fields) ->
renStructElts fields
env
| TypeBlock(_, _, fields) ->
// treat the fields as if they were global variables
renList env (renDecl Level.TopLevel) fields
Expand Down
7 changes: 1 addition & 6 deletions src/rewriter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ open Builtin
open Ast
open Options.Globals

let renameField field =
if isFieldSwizzle field then
field |> String.map (fun c -> options.canonicalFieldNames.[swizzleIndex c])
else field

let private commaSeparatedExprs = List.reduce (fun a b -> FunCall(Op ",", [a; b]))

let rec private sideEffects = function
Expand Down Expand Up @@ -336,7 +331,7 @@ module private RewriterImpl =
| FunCall(Var constr, args) when constr.Name = "vec2" || constr.Name = "vec3" || constr.Name = "vec4" ->
simplifyVec constr args

| Dot(e, field) when options.canonicalFieldNames <> "" -> Dot(e, renameField field)
| Dot(e, field) when options.canonicalFieldNames <> "" -> Dot(e, Renamer.renameField field)

| Var s as e ->
match env.vars.TryFind s.Name with
Expand Down
1 change: 1 addition & 0 deletions tests/commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
--no-remove-unused --format indented -o tests/unit/interface_block.frag.expected tests/unit/interface_block.frag
--no-remove-unused --no-renaming --format indented -o tests/unit/ternary.frag.expected tests/unit/ternary.frag
--no-remove-unused --no-renaming --format indented -o tests/unit/reuse-var.frag.expected tests/unit/reuse-var.frag
--no-remove-unused --format indented -o tests/unit/struct.frag.expected tests/unit/struct.frag

# Unused removal tests

Expand Down
14 changes: 14 additions & 0 deletions tests/unit/struct.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
struct Foo {
int field1;
int field2;
int ab;
int st;
};

void main() {
Foo f;
f.field1 = 1;
f.field2 = 2;
f.ab = 3;
f.st = 4;
}
9 changes: 9 additions & 0 deletions tests/unit/struct.frag.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
struct Foo{int field1;int field2;int wz;int xy;};
void main()
{
Foo i;
i.field1=1;
i.field2=2;
i.wz=3;
i.xy=4;
}