blob: 614a6a0dbc1bdc79c565aab750359ae52a458e55 [file] [log] [blame]
{{/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/}}
{{Global "module" ""}}
{{Include "go_common.tmpl"}}
{{$ | Macro "replay_writer.go" | GoFmt | Write "replay_writer.go"}}
{{define "replay_writer.go"}}
{{template "Go.GeneratedHeader" (Global "OutputDir")}}
import (
"fmt"
"io"
"io/ioutil"
"strings"
"android.googlesource.com/platform/tools/gpu/atom"
"android.googlesource.com/platform/tools/gpu/binary"
"android.googlesource.com/platform/tools/gpu/database"
"android.googlesource.com/platform/tools/gpu/log"
"android.googlesource.com/platform/tools/gpu/memory"
"android.googlesource.com/platform/tools/gpu/replay/builder"
"android.googlesource.com/platform/tools/gpu/replay/protocol"
"android.googlesource.com/platform/tools/gpu/replay/value"
)
{{Global "Go.Statement.Override" "Statement"}}
func loadRemapb *builder.Builder, key interface{}, ty protocol.Type, val value.Value) {
if ptr, found := ϟb.Remappings[key]; found {
ϟb.Load(ty, ptr)
} else {
ptr = ϟb.AllocateMemory(uint64(ty.Sizeb.Architecture().PointerSize)))
ϟb.Push(val) // We have an input to an unknown id, use the unmapped value.
ϟb.Clone(0)
ϟb.Store(ptr)
ϟb.Remappings[key] = ptr
}
}
{{Template "DeclareBuilderFunctionInfos" $}}
{{ForEach $.Pseudonyms "DeclarePseudonymValue" | JoinWith "\n"}}
{{ForEach (AllCommands $) "DeclareCommandReplay" | JoinWith "\n"}}
{{ForEach $.Pointers "PointerReplayMethods" | JoinWith "\n"}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the replay function for the specified command
-------------------------------------------------------------------------------
*/}}
{{define "DeclareCommandReplay"}}
{{AssertType $ "Function"}}
{{if not (GetAnnotation $ "no_replay")}}
{{$name := Macro "Go.CmdName" $}}
var _ = replay.Replayer(&{{$name}}{}) // interface compliance check
func a *{{$name}}) {{if GetAnnotation $ "replay_custom"}}default{{end}}Replay
ϟi atom.ID, ϟs *gfxapi.State, ϟd database.Database, ϟl log.Logger, ϟb *builder.Builder) error {
ϟc := getStates)
_ = ϟc
{{Global "CurrentCommand" $}}
{{/* Simulate the call */}}
{{Template "Go.CommandLogic" $}}
return nil
}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits logic to push the specified input variable to the VM's stack.
-------------------------------------------------------------------------------
*/}}
{{define "PushInput"}}
{{AssertType $.Type "Type"}}
{{AssertType $.Name "string"}}
{{if (GetAnnotation $.Type "replay_remap")}}
if key, remap := {{$.Name}}.remapa, ϟs); remap {
loadRemapb, key, {{Template "Go.Replay.Type" $.Type}}, {{Template "Go.Replay.Value" "Type" $.Type "Name" $.Name}})
} else {
ϟb.Push({{Template "Go.Replay.Value" "Type" $.Type "Name" $.Name}})
}
{{else}}
ϟb.Push({{Template "Go.Replay.Value" "Type" $.Type "Name" $.Name}})
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Declares the value method for a given pseudonym type.
-------------------------------------------------------------------------------
*/}}
{{define "DeclarePseudonymValue"}}
{{AssertType $ "Pseudonym"}}
{{$u := $ | TypeOf | Underlying}}
{{if or (IsNumericType $u) (IsPointer $u)}}
{{if not (GetAnnotation $ "replay_custom_value")}}
{{$v := print (Macro "Go.Type" $.To) "(c)"}}
func (c {{$.Name}}) valueb *builder.Builder, ϟa atom.Atom, ϟs *gfxapi.State) value.Value { return {{Template "Go.Replay.Value" "Type" $.To "Name" $v}} }
{{end}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Declares the value method for the given static array type.
-------------------------------------------------------------------------------
*/}}
{{define "DeclareArrayValue"}}
{{AssertType $ "Array" "StaticArray"}}
{{if not (or (Macro "IsInternal" $.ValueType) (IsAny $.ValueType))}}
func (arr {{Template "Go.Type" $}}) valueb *builder.Builder, ϟa atom.Atom, ϟs *gfxapi.State) value.Pointer {
if len(arr) > 0 {
for _, e := range arr {
{{Template "PushInput" "Type" $.ValueType "Name" "e"}}
}
return ϟb.Buffer(len(arr))
} else {
return value.AbsolutePointer(0)
}
}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits a function info definition for each of the commands.
-------------------------------------------------------------------------------
*/}}
{{define "DeclareBuilderFunctionInfos"}}
{{AssertType $ "API"}}
{{range $i, $c := AllCommands $}}
var {{Template "BuilderFunctionInfo" $c}} = builder.FunctionInfo
ID: {{$i}},§
ReturnType: {{Template "Go.Replay.Type" $c.Return.Type}},§
Parameters: {{len $c.CallParameters}},§
}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the name of the variable holding the specified command's function id.
-------------------------------------------------------------------------------
*/}}
{{define "BuilderFunctionInfo"}}{{AssertType $ "Function"}}funcInfo{{Template "Go.CmdName" $}}{{end}}
{{/*
-------------------------------------------------------------------------------
An override for the "Go.Statement" macro.
-------------------------------------------------------------------------------
*/}}
{{define "Statement"}}
{{ if IsFence $}}{{Template "Fence" $}}
{{else if IsReturn $}}{{/* no-op */}}
{{else}}{{Template "Go.Statement.Default" $}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
An override for the "Go.Fence" macro.
-------------------------------------------------------------------------------
*/}}
{{define "Fence"}}
{{AssertType $ "Fence"}}
{{$c := Global "CurrentCommand"}}
{{AssertType $c "Function"}}
{{if not (IsNil $.Statement)}}
{{if IsCopy $.Statement}}
{{/* Apply the fenced-copy read */}}
{{/* TODO: Unlike Slice.Copy, this does not optimise for non-pointer copies. */}}
ϟdst, ϟsrc := {{Template "Go.Read" $.Statement.Dst}}, {{Template "Go.Read" $.Statement.Src}}
ϟcount := mindst.Count, ϟsrc.Count)
ϟdst, ϟsrc = ϟdst.Slice(0, ϟcount, ϟs), ϟsrc.Slice(0, ϟcount, ϟs)
ϟsrcElems := ϟsrc.Reada, ϟs, ϟd, ϟl, ϟb)
{{end}}
{{end}}
{{/* Push all the parameters on the stack */}}
{{range $p := $c.CallParameters}}
{{$type := TypeOf $p}}
{{$name := print "ϟa." (Macro "Go.Parameter" $p)}}
{{Template "PushInput" "Type" $type "Name" $name}}
{{end}}
{{/* Call the function */}}
ϟb.Call({{Template "BuilderFunctionInfo" $c}})
{{/* Store the return value into a remapping table, if required */}}
{{$rty := TypeOf $c.Return}}
{{if (GetAnnotation $rty "replay_remap")}}
if key, remap := ϟa.Result.remapa, ϟs); remap {
ptr, found := ϟb.Remappings[key]
if !found {
ptr = ϟb.AllocateMemory({{Template "Go.SizeOf" $rty}})
ϟb.Remappings[key] = ptr
}
ϟb.Clone(0)
ϟb.Store(ptr)
}
{{end}}
{{/* Merge the observed writes into the application pool */}}
ϟa.observations.ApplyWritess.Memory[memory.ApplicationPool])
{{/* Perform the fenced statement */}}
{{if not (IsNil $.Statement)}}
{{if IsCopy $.Statement}}
{{/* Apply the fenced-copy write */}}
ϟdst.WritesrcElems, ϟa, ϟs, ϟd, ϟl, ϟb)
{{else}}
{{Template "Go.Statement" $.Statement}}
{{end}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits additional methods used for replay generation for the Pointer type or
indirect type (Pseudonym) to Pointer.
-------------------------------------------------------------------------------
*/}}
{{define "PointerReplayMethods"}}
{{AssertType $ "Pointer" "Pseudonym"}}
{{$p := $ | Underlying | Unpack }}
{{$ptr_ty := Macro "Go.Type" $ }}
{{$el_ty := Macro "Go.Type" $p.To }}
{{$el_is_void := IsVoid ($p.To | Underlying | Unpack)}}
func (p {{$ptr_ty}}) value() value.Pointer {
if p.Address != 0 {
return value.RemappedPointer(p.Address)
} else {
return value.AbsolutePointer(0)
}
}
{{end}}