Browse Source

* fixed some small issues (while testing old shader code)

master
Bergmann89 8 years ago
parent
commit
fc7e3feaa8
15 changed files with 282 additions and 241 deletions
  1. +1
    -1
      uengShaderCodePart.pas
  2. +3
    -3
      uengShaderFile.inc
  3. +5
    -42
      uengShaderFile.pas
  4. +5
    -5
      uengShaderFileExpression.pas
  5. +13
    -0
      uengShaderFileHelper.pas
  6. +1
    -1
      uengShaderFileParser.pas
  7. +2
    -2
      uengShaderFileTypes.pas
  8. +54
    -4
      uengShaderGenerator.pas
  9. +156
    -136
      uengShaderGeneratorArgs.pas
  10. +1
    -1
      uengShaderPart.pas
  11. +7
    -24
      uengShaderPartClass.pas
  12. +13
    -15
      uengShaderPartCntr.pas
  13. +2
    -1
      uengShaderPartIf.pas
  14. +16
    -4
      uengShaderPartKeyValuePair.pas
  15. +3
    -2
      uengShaderPartProc.pas

+ 1
- 1
uengShaderCodePart.pas View File

@@ -9,7 +9,7 @@ uses
Classes, SysUtils,
uengShaderPart, uengShaderFileParser, uengShaderGeneratorArgs

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;


+ 3
- 3
uengShaderFile.inc View File

@@ -1,3 +1,3 @@
{.$DEFINE EXPRESSION_ADD_BRACKET} // add brackets to expressions
{$DEFINE USE_BITSPACE_UTILS} // use bitSpace Utils
{.$DEFINE DEBUG} // enable debug output
{.$DEFINE DEBUGEXPRESSION_ADD_BRACKET} // add brackets to expressions
{$DEFINE SHADER_FILE_USE_BITSPACE_UTILS} // use bitSpace Utils
{.$DEFINE SHADER_FILE_DEBUG} // enable debug output

+ 5
- 42
uengShaderFile.pas View File

@@ -13,9 +13,9 @@ interface
uses
Classes, sysutils,
uengShaderPart, uengShaderPartClass, uengShaderFileParser, uengShaderFileTypes,
uengShaderGenerator, uengShaderGeneratorArgs
uengShaderGenerator

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlSerialization
{$ENDIF}
;
@@ -44,10 +44,6 @@ type
procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);

{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General }
private
fOnLog: TengShaderFileLogEvent;
@@ -68,7 +64,7 @@ type
implementation

uses
uengShaderPartInclude, uengShaderPartKeyValuePair, uengShaderFileHelper, uengShaderPartProc;
uengShaderPartInclude, uengShaderPartKeyValuePair, uengShaderFileHelper;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -105,13 +101,13 @@ procedure TengShaderFile.UpdateClasses;
s: String;
begin
c := fClasses[aClass.Name];
if Assigned(c) then begin
if Assigned(c) and (c <> aClass) then begin
s := Format('use of duplicate identifier: %s (%s %d:%d)', [aClass.Name, aClass.Filename, aClass.Line + 1, aClass.Col]) + sLineBreak +
'previously declared here:' + sLineBreak +
Format(' %s %d:%d', [c.Filename, c.Line + 1, c.Col]) + sLineBreak;
LogMsg(llWarning, s);
fClasses[aClass.Name] := aClass;
end else
end else if (c <> aClass) then
fClasses.Add(aClass.Name, aClass);
end;

@@ -260,39 +256,6 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var
sr: TengSearchResults;
walker: TengSearchWalker;
main: TengShaderPartMain;
begin
inherited GenerateCodeIntern(aArgs);
if (aArgs.Root = self) then begin
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
try
walker.SearchFlags := [sfSearchChildren, sfEvaluateIf];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartMain);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.Run(self);
main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr, []) as TengShaderPartMain);
if Assigned(main) then begin
aArgs.PushFlags((aArgs.Flags * [gfAddProcedureItem, gfAddParameterItem]) + [gfGenerateProcedureCode]);
try
main.GenerateCodeIntern(aArgs);
finally
aArgs.PopFlags;
end;
end;
finally
FreeAndNil(walker);
FreeAndNil(sr);
end;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
var


+ 5
- 5
uengShaderFileExpression.pas View File

@@ -343,9 +343,9 @@ begin
if not Assigned(fChild) then
EengExpression.Create('no child assigned', self);
result :=
{$IFDEF EXPRESSION_ADD_BRACKET}TOKEN_OP_GROUP_BEGIN+{$ENDIF}
{$IFDEF SHADER_FILE_EXPRESSION_ADD_BRACKET}TOKEN_OP_GROUP_BEGIN+{$ENDIF}
EXPRESSION_UNARY_OPERATIONS[fUnaryOp] + ' ' + fChild.GetText
{$IFDEF EXPRESSION_ADD_BRACKET}+TOKEN_OP_GROUP_END{$ENDIF};
{$IFDEF SHADER_FILE_EXPRESSION_ADD_BRACKET}+TOKEN_OP_GROUP_END{$ENDIF};
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -439,9 +439,9 @@ begin
if not Assigned(fFirst) or not Assigned(fSecond) then
raise EengExpression.Create('first or second item not assigned');
result :=
{$IFDEF EXPRESSION_ADD_BRACKET}TOKEN_OP_GROUP_BEGIN +{$ENDIF}
{$IFDEF SHADER_FILE_EXPRESSION_ADD_BRACKET}TOKEN_OP_GROUP_BEGIN +{$ENDIF}
fFirst.GetText + ' ' + EXPRESSION_BINARY_OPERATIONS[fBinaryOp] + ' ' + fSecond.GetText
{$IFDEF EXPRESSION_ADD_BRACKET} + TOKEN_OP_GROUP_END{$ENDIF};
{$IFDEF SHADER_FILE_EXPRESSION_ADD_BRACKET} + TOKEN_OP_GROUP_END{$ENDIF};
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -693,7 +693,7 @@ begin
walker := TengKeyValuePairSearchWalker.Create(sr);
try
walker.Name := param.Name;
walker.SearchFlags := [sfSearchChildren, sfSearchParents];
walker.SearchFlags := [sfSearchChildren, sfSearchParents, sfSearchInherited];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);


+ 13
- 0
uengShaderFileHelper.pas View File

@@ -41,6 +41,7 @@ type

TengSearchResults = class(TengShaderPartList)
public
function Add(const aItem: TengShaderPart): Integer; reintroduce;
constructor Create;
end;

@@ -193,6 +194,18 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengSearchResults.Add(const aItem: TengShaderPart): Integer;
var
i: Integer;
begin
result := -1;
for i := 0 to Count-1 do
if (Items[i] = aItem) then
exit;
result := inherited Add(aItem);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 1
- 1
uengShaderFileParser.pas View File

@@ -9,7 +9,7 @@ uses
Classes, SysUtils,
uengShaderFileTypes

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlGenerics
{$ELSE}
, fgl


+ 2
- 2
uengShaderFileTypes.pas View File

@@ -8,14 +8,14 @@ interface
uses
Classes, SysUtils

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlSerialization, uutlCommon, uutlGenerics
{$ENDIF}
;

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
IengShaderFileWriter = uutlSerialization.IutlFileWriter;
IengShaderFileReader = uutlSerialization.IutlFileReader;
TengShaderFileReader = uutlSerialization.TutlSimpleFileReader;


+ 54
- 4
uengShaderGenerator.pas View File

@@ -47,6 +47,9 @@ type

implementation

uses
uengShaderFile, uengShaderFileHelper, uengShaderPartProc, uengShaderPartParameter;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderGenerator///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -98,13 +101,16 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGenerator.AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean);
var
i: Integer;
l: TengShaderPartPropertyList;
p: TengShaderPartProperty;
s: String;
begin
i := -1;
l := fPropertyMap[aProp.Name];
if Assigned(l) then begin
if aShowWarning then begin
i := l.IndexOf(aProp);
if aShowWarning and (i >= 0) then begin
p := l.Last;
s := Format('use of duplicate identifier: %s (%s %d:%d)', [aProp.Name, aProp.Filename, aProp.Line + 1, aProp.Col]) + sLineBreak +
'previously declared here:' + sLineBreak +
@@ -115,9 +121,11 @@ begin
l := TengShaderPartPropertyList.Create;
fPropertyMap.Add(aProp.Name, l);
end;
l.Add(aProp);
if (aProp.Value <> Unassigned) then
l.Value := aProp.Value;
if (i < 0) then begin
l.Add(aProp);
if (aProp.Value <> Unassigned) then
l.Value := aProp.Value;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -148,11 +156,53 @@ end;
procedure TengShaderGenerator.GenerateCode(const aCode: TengShaderCode);
var
args: TengShaderGeneratorArgs;
sr: TengSearchResults;
walker: TengSearchWalker;
main: TengShaderPartMain;
begin
args := TengShaderGeneratorArgs.Create(self);
try
fPropertyMap.ApplyValues;
GenerateCodeIntern(args);

args.PushCode;
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
try
walker.SearchFlags := [sfSearchChildren, sfEvaluateIf];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartMain);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.Run(self);
if (self is TengShaderFile)
then main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr, []) as TengShaderPartMain)
else main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr) as TengShaderPartMain);
if Assigned(main) then begin
args.PushFlags((args.Flags * [gfAddProcedureItem, gfAddParameterItem]) + [gfGenerateProcedureCode, gfGenerateProcedureMain]);
try
main.GenerateCodeIntern(args);
finally
args.PopFlags;
end;
end;

args.GenerateProcedureCode;
args.GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartVar));
args.GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartVarying));
args.GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartUniform));
finally
FreeAndNil(walker);
FreeAndNil(sr);
args.PopCode([pcfAppend, pcfAddEmptyLine]);
end;

args.PushCode;
try
args.GenerateMetaCode;
finally
args.PopCode([pcfPrepend, pcfAddEmptyLine]);
end;

args.GenerateCode(aCode);
finally
FreeAndNil(args);


+ 156
- 136
uengShaderGeneratorArgs.pas View File

@@ -9,7 +9,7 @@ uses
Classes, SysUtils,
uengShaderFileTypes, uengShaderPart

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;
@@ -38,13 +38,14 @@ type
TengShaderGeneratorArgs = class(TObject)
private type
TengGeneratorToken = (
gtNormal = 0, // normal text
gtLineBreak = 1, // line break
gtCommandEnd = 2, // command end (like ';')
gtBlockBegin = 3, // code block begin (to calculate indent)
gtBlockEnd = 4, // code block end (to calculate indent)
gtAppendToPrev = 5, // append current line to prev line
gtToken = 6 // code token (like '$INCLUDE' or '$IF')
gtNormal = 0, // normal text
gtLineBreak = 1, // line break
gtCommandEnd = 2, // command end (like ';')
gtBlockBegin = 3, // code block begin (to calculate indent)
gtBlockEnd = 4, // code block end (to calculate indent)
gtAppendToPrev = 5, // append current line to prev line
gtIgnoreNextCommandEnd = 6, // ignore next command end
gtToken = 7 // code token (like '$INCLUDE' or '$IF')
);

TCodePart = class(TObject)
@@ -100,10 +101,6 @@ type

function GetFlags: TengGenerateFlags;
function GetProcParams: TStrings;

procedure GenerateParameterCode(const aTypes: CengShaderPartArr);
procedure GenerateProcedureCode;
procedure GenerateMetaCode;
public
property Root: TengShaderPart read fRoot;
property Flags: TengGenerateFlags read GetFlags;
@@ -125,6 +122,7 @@ type
function BeginBlock(const aIndent: Integer = High(Integer)): TengShaderGeneratorArgs;
function EndBlock(const aCanAppend: Boolean = false): TengShaderGeneratorArgs;
function AppendToPrevLine: TengShaderGeneratorArgs;
function IgnoreNextCommandEnd: TengShaderGeneratorArgs;

procedure AddMeta(const aMeta: TengMetaData);
procedure AddParameter(const aParam: TengShaderPart);
@@ -134,6 +132,10 @@ type
function ReplaceIdents(const aOld, aNew: TStrings): TengShaderGeneratorArgs;
function ReplaceReturns(const aCommand: TCodeStackItem; const aRetType, aName: String): TengShaderGeneratorArgs;

procedure GenerateParameterCode(const aTypes: CengShaderPartArr);
procedure GenerateProcedureCode;
procedure GenerateMetaCode;

procedure GenerateCode(const aCode: TengShaderCode);

constructor Create(const aRoot: TengShaderPart);
@@ -267,10 +269,11 @@ end;
procedure TengShaderGeneratorArgs.TCodeStackItem.GenerateCode(const aCode: TengShaderCode);
type
TGenFlag = (
gfToken, // current line has a token in it
gfTokenOnly, // current line has only a token (or whitespaces) in it
gfPrevIsEmpty, // previouse line was empty (or whitespaces only)
gfAddToPrev // add current line to previouse line
gfToken, // current line has a token in it
gfTokenOnly, // current line has only a token (or whitespaces) in it
gfPrevIsEmpty, // previouse line was empty (or whitespaces only)
gfAddToPrev, // add current line to previouse line
gfIgnoreNextCommandEnd
);
TGenFlags = set of TGenFlag;

@@ -279,7 +282,7 @@ var
f: TGenFlags;
cb: TCodeBlock;

{$IFDEF DEBUG}
{$IFDEF SHADER_FILE_DEBUG}
procedure GenerateDebugCode;
var
cp: TCodePart;
@@ -359,6 +362,7 @@ var
var
cp: TCodePart;
tmp: Integer;
s: String;
begin
while (i < fItems.Count) do begin
cp := fItems[i];
@@ -406,22 +410,36 @@ var
end;

gtBlockEnd: begin
{$IFDEF DEBUG}
{$IFDEF SHADER_FILE_DEBUG}
GenerateCurrentCode(Format('------====== DEBUG STEP BEFORE INDENT (%d) ======------', [aCurrentBlockIndent]));
{$ENDIF}
IndentBlock(aDepth, aCurrentBlockIndent);
{$IFDEF DEBUG}
{$IFDEF SHADER_FILE_DEBUG}
GenerateCurrentCode(Format('------====== DEBUG STEP AFTER INDENT (%d) ======------', [aCurrentBlockIndent]));
{$ENDIF}
exit;
end;

gtIgnoreNextCommandEnd: begin
include(f, gfIgnoreNextCommandEnd);
end;

gtAppendToPrev: begin
if (Trim(cb.Last) = '') and not (gfPrevIsEmpty in f) then
include(f, gfAddToPrev);
end;

gtCommandEnd: begin
if (gfIgnoreNextCommandEnd in f)
then exclude(f, gfIgnoreNextCommandEnd)
else cb.Last := cb.Last + cp.Code;
end;

else
cb.Last := cb.Last + cp.Code;
s := cp.Code;
if (Trim(s) <> '') then
exclude(f, gfIgnoreNextCommandEnd);
cb.Last := cb.Last + s;
end;
end;
end;
@@ -429,7 +447,7 @@ var
var
s, e: Integer;
begin
{$IFDEF DEBUG}
{$IFDEF SHADER_FILE_DEBUG}
GenerateDebugCode;
{$ENDIF}

@@ -446,7 +464,7 @@ begin
dec(e);
for i := s to e do
aCode.Add(
{$IFDEF DEBUG}
{$IFDEF SHADER_FILE_DEBUG}
Format('[%02d]%s|', [cb.Depth[i], cb[i]])
{$ELSE}
cb[i]
@@ -496,113 +514,6 @@ begin
result := fProcParams.Last;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateParameterCode(const aTypes: CengShaderPartArr);
var
m: TParameterMap;
p: TengShaderPart;
begin
PushCode;
PushFlags(Flags + [gfGenerateParameterCode] - [gfAddParameterItem]);
m := TParameterMap.Create(false);
try
fMaxParameterLength := 0;
for p in fParameters do begin
if CheckType(p, aTypes) then with (p as TengShaderPartParameter) do begin
fMaxParameterLength := Max(fMaxParameterLength, Length(Typ));
m.Add(Typ+Name, p);
end;
end;
for p in m do begin
(p as TengShaderPartParameter).GenerateCodeIntern(self);
AddLineBreak;
end;
finally
FreeAndNil(m);
PopFlags;
PopCode([pcfPrepend, pcfAddEmptyLine]);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateProcedureCode;
var
i: Integer;
begin
i := 0;
while (i < fProcedures.Count) do begin
PushCode;
PushFlags([gfGenerateProcedureCode, gfAddParameterItem]);
try
(fProcedures[i] as TengShaderPartProc).GenerateCodeIntern(self);
finally
PopFlags;
PopCode([pcfPrepend, pcfAddEmptyLine]);
end;
inc(i);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateMetaCode;
var
layouts: TStringList;
m: TengMetaData;
vCompat: Boolean;
vMax, i: Integer;
s: String;
begin
PushCode;
vMax := 0;
vCompat := false;
layouts := TStringList.Create;
try
for m in fMetaDataList do begin
case m.MetaType of
metaVersion: begin
if (m.Values[0] = VERSION_EXTRA_COMPAT) then
vCompat := true
else if TryStrToInt(m.Values[0], i) then
vMax := max(vMax, i);
if (m.Count > 1) and (m.Values[1] = VERSION_EXTRA_COMPAT) then
vCompat := true;
end;

metaExtension: begin
AddText(format('#extension %s : %s', [m.Values[0], m.Values[1]]));
AddLineBreak;
end;

metaLayout: begin
layouts.Add('layout' + m.Values[0] + ';');
end;
end;
end;

if (vMax >= LAYOUT_MIN_VERSION) then begin
for s in layouts do begin
AddText(s);
AddLineBreak;
end;
end;

if (vMax > 0) then begin
PushCode;
try
AddText('#version ' + IntToStr(vMax));
if vCompat then
AddText(' ' + VERSION_EXTRA_COMPAT);
AddLineBreak;
finally
PopCode([pcfPrepend]);
end;
end;
finally
PopCode([pcfPrepend, pcfAddEmptyLine]);
FreeAndNil(layouts);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderGeneratorArgs.PushCode: TengShaderGeneratorArgs;
begin
@@ -711,6 +622,13 @@ begin
result := self;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderGeneratorArgs.IgnoreNextCommandEnd: TengShaderGeneratorArgs;
begin
fCode.Last.Items.Add(TCodePart.Create(gtIgnoreNextCommandEnd, ''));
result := self;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.AddMeta(const aMeta: TengMetaData);
begin
@@ -727,13 +645,13 @@ begin
raise EengShaderPartInternal.Create('parameter (' + aParam.ClassName + ') is not a ' + TengShaderPartParameter.ClassName, aParam);
with (aParam as TengShaderPartParameter) do begin
p := fParameters[Name];
if Assigned(p) then begin
if Assigned(p) and (p <> aParam) then begin
s := Format('use of duplicate identifier: %s (%s %d:%d)', [Name, Filename, Line + 1, Col]) + sLineBreak +
'previously declared here:' + sLineBreak +
Format(' %s %d:%d', [p.Filename, p.Line + 1, p.Col]) + sLineBreak;
fRoot.LogMsg(llWarning, s);
fParameters[Name] := aParam;
end else
end else if (p <> aParam) then
fParameters.Add(Name, aParam);
end;
end;
@@ -883,14 +801,116 @@ begin
result := self;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateParameterCode(const aTypes: CengShaderPartArr);
var
m: TParameterMap;
p: TengShaderPart;
begin
PushCode;
PushFlags(Flags + [gfGenerateParameterCode] - [gfAddParameterItem]);
m := TParameterMap.Create(false);
try
fMaxParameterLength := 0;
for p in fParameters do begin
if CheckType(p, aTypes) then with (p as TengShaderPartParameter) do begin
fMaxParameterLength := Max(fMaxParameterLength, Length(Typ));
m.Add(Typ+Name, p);
end;
end;
for p in m do begin
(p as TengShaderPartParameter).GenerateCodeIntern(self);
AddLineBreak;
end;
finally
FreeAndNil(m);
PopFlags;
PopCode([pcfPrepend, pcfAddEmptyLine]);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateProcedureCode;
var
i: Integer;
begin
i := 0;
while (i < fProcedures.Count) do begin
PushCode;
PushFlags([gfGenerateProcedureCode, gfAddParameterItem]);
try
(fProcedures[i] as TengShaderPartProc).GenerateCodeIntern(self);
finally
PopFlags;
PopCode([pcfPrepend, pcfAddEmptyLine]);
end;
inc(i);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateMetaCode;
var
layouts: TStringList;
m: TengMetaData;
vCompat: Boolean;
vMax, i: Integer;
s: String;
begin
PushCode;
vMax := 0;
vCompat := false;
layouts := TStringList.Create;
try
for m in fMetaDataList do begin
case m.MetaType of
metaVersion: begin
if (m.Values[0] = VERSION_EXTRA_COMPAT) then
vCompat := true
else if TryStrToInt(m.Values[0], i) then
vMax := max(vMax, i);
if (m.Count > 1) and (m.Values[1] = VERSION_EXTRA_COMPAT) then
vCompat := true;
end;

metaExtension: begin
AddText(format('#extension %s : %s', [m.Values[0], m.Values[1]]));
AddLineBreak;
end;

metaLayout: begin
layouts.Add('layout' + m.Values[0] + ';');
end;
end;
end;

if (vMax >= LAYOUT_MIN_VERSION) then begin
for s in layouts do begin
AddText(s);
AddLineBreak;
end;
end;

if (vMax > 0) then begin
PushCode;
try
AddText('#version ' + IntToStr(vMax));
if vCompat then
AddText(' ' + VERSION_EXTRA_COMPAT);
AddLineBreak;
finally
PopCode([pcfPrepend]);
end;
end;
finally
PopCode([pcfPrepend, pcfAddEmptyLine]);
FreeAndNil(layouts);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateCode(const aCode: TengShaderCode);
begin
GenerateProcedureCode;
GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartVar));
GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartVarying));
GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartUniform));
GenerateMetaCode;
fCode.Last.GenerateCode(aCode);
end;



+ 1
- 1
uengShaderPart.pas View File

@@ -10,7 +10,7 @@ uses

uengShaderFileParser, uengShaderFileTypes

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlGenerics
{$ELSE}
, fgl


+ 7
- 24
uengShaderPartClass.pas View File

@@ -9,7 +9,7 @@ uses
Classes, SysUtils,
uengShaderPart, uengShaderGenerator, uengShaderGeneratorArgs, uengShaderFileParser

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;
@@ -56,7 +56,7 @@ implementation

uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartKeyValuePair,
uengShaderPartScope, uengShaderFile, uengShaderPartProc;
uengShaderPartScope, uengShaderFile;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartClass///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -174,9 +174,9 @@ begin
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
try
walker.SearchFlags := [sfSearchChildren];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass);
walker.Run(self);
for p in sr.GetReverseEnumerator do
AddProperty(p as TengShaderPartProperty);
@@ -190,32 +190,15 @@ end;
procedure TengShaderPartClass.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var
c: TengShaderPartClass;
sr: TengSearchResults;
walker: TengSearchWalker;
main: TengShaderPartMain;
begin
if (aArgs.Root <> self) then
exit;
for c in fInherited do
c.GenerateCodeIntern(aArgs);
inherited GenerateCodeIntern(aArgs);

sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
aArgs.BeginBlock;
try
walker.SearchFlags := [sfSearchChildren, sfEvaluateIf];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartMain);
walker.Run(self);
main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr) as TengShaderPartMain);
aArgs.PushFlags([gfGenerateProcedureCode, gfGenerateProcedureMain]);
try
main.GenerateCodeIntern(aArgs);
finally
aArgs.PopFlags;
end;
inherited GenerateCodeIntern(aArgs);
finally
FreeAndNil(walker);
FreeAndNil(sr);
aArgs.EndBlock;
end;
end;



+ 13
- 15
uengShaderPartCntr.pas View File

@@ -15,13 +15,14 @@ type
{ Code Loading & Storage }
private
fChildren: TengShaderCodePartList;
procedure AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean = false);
function HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
protected { virtual getter }
function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override;
function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
public
procedure AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean = false);

{ Code Generation }
public
@@ -40,13 +41,13 @@ uses
uengShaderPartKeyValuePair, uengShaderPartClass, uengShaderPartMessage, uengShaderPartMeta,
uengShaderPartCall, uengShaderPartProc, uengShaderPartText, uengShaderPartEcho, uengShaderPartIf,
uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment, uengShaderFileConstants
{$IFDEF DEBUG}
{$IFDEF SHADER_FILE_DEBUG}
, uengShaderFileTypes
{$ENDIF}
;

const
TOKEN_CLASSES: array[0..21] of CengShaderCodePart = (
TOKEN_CLASSES: array[0..22] of CengShaderCodePart = (
TengShaderPartCall,
TengShaderPartClass,
TengShaderPartConst,
@@ -65,6 +66,7 @@ const
TengShaderPartMeta,
TengShaderPartProc,
TengShaderPartProperty,
TengShaderPartThrow,
TengShaderPartUniform,
TengShaderPartVar,
TengShaderPartVarying,
@@ -73,14 +75,6 @@ const

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartCntr////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCntr.AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean);
begin
if aPrepend
then fChildren.PushFirst(aChild)
else fChildren.PushLast(aChild);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartCntr.HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
var
@@ -96,10 +90,6 @@ begin
break;
end;
end;
{$IFDEF DEBUG}
if Assigned(p) then
LogMsg(llDebug, 'ParseText: ' + p.ClassName);
{$ENDIF}
if Assigned(p)
then result := p.ParseText(aArgs)
else result := aToken;
@@ -150,6 +140,14 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCntr.AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean);
begin
if aPrepend
then fChildren.PushFirst(aChild)
else fChildren.PushLast(aChild);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCntr.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var


+ 2
- 1
uengShaderPartIf.pas View File

@@ -169,7 +169,8 @@ begin
if Assigned(p) then begin
p.GenerateCodeIntern(aArgs);
aArgs.AppendToPrevLine;
end;
end else
aArgs.AddToken(GetTokenName);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 16
- 4
uengShaderPartKeyValuePair.pas View File

@@ -7,9 +7,9 @@ interface

uses
Classes, SysUtils, variants,
uengShaderCodePart, uengShaderFileParser
uengShaderPart, uengShaderCodePart, uengShaderFileParser

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;
@@ -34,6 +34,8 @@ type
property ValueName: String read fValueName;
property Value: Variant read fValue;
property DefaultValue: Variant read fDefaultValue;

constructor Create(const aParent: TengShaderPart; const aName: String; const aValue: Variant); overload;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -48,7 +50,7 @@ type
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartPropertyList = class(specialize TutlSimpleList<TengShaderPartProperty>)
TengShaderPartPropertyList = class(specialize TutlList<TengShaderPartProperty>)
private
fValue: Variant;
public
@@ -72,7 +74,7 @@ type
implementation

uses
uengShaderPart, uengShaderFile, uengShaderPartScope, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderFile, uengShaderPartScope, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartPropertyList/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -163,6 +165,16 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartKeyValuePair.Create(const aParent: TengShaderPart; const aName: String; const aValue: Variant);
begin
inherited Create(aParent);
fName := aName;
fValueName := '';
fValue := aValue;
fDefaultValue := aValue;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartProperty////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 3
- 2
uengShaderPartProc.pas View File

@@ -9,7 +9,7 @@ uses
Classes, SysUtils,
uengShaderPart, uengShaderPartScope, uengShaderFileParser, uengShaderGeneratorArgs

{$IFDEF USE_BITSPACE_UTILS}
{$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
, uutlGenerics;
{$ELSE}
, fgl;
@@ -250,7 +250,8 @@ begin
((gfGenerateInlineCode in aArgs.Flags) or fIsInline) then
begin
GenerateInlineCode(aArgs);
// TODO: ignore next command end?!
if (GetTokenName = TOKEN_PROC) then
aArgs.IgnoreNextCommandEnd;

// generate code
end else if (gfGenerateProcedureCode in aArgs.Flags) then begin


Loading…
Cancel
Save