Skip to content

Commit

Permalink
Handle initial commands
Browse files Browse the repository at this point in the history
For initial commands, their IDs are assigned to 0, and linearized ID
(the label) will be specified in the message.
  • Loading branch information
Qining committed Jun 1, 2018
1 parent d5b0107 commit 17b5ac2
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 54 deletions.
24 changes: 24 additions & 0 deletions gapis/api/vulkan/extensions/ext_debug_report.api
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,17 @@ cmd VkResult vkCreateDebugReportCallbackEXT(
AllocationCallbacks pAllocator,
VkDebugReportCallbackEXT* pCallback) {
if !(instance in Instances) { vkErrorInvalidInstance(instance) }
if pCreateInfo == null { vkErrorNullPointer("VkDebugReportCallbackCreateInfoEXT") }
info := pCreateInfo[0]
handle := ?
if pCallback == null { vkErrorNullPointer("VkDebugReportCallbackEXT") }
pCallback[0] = handle
object := new!DebugReportCallbackObject(
Instance: instance,
Flags: info.flags,
VulkanHandle: handle,
)
DebugReportCallbacks[handle] = object
return ?
}

Expand All @@ -165,6 +176,9 @@ cmd void vkDestroyDebugReportCallbackEXT(
VkDebugReportCallbackEXT callback,
AllocationCallbacks pAllocator) {
if !(instance in Instances) { vkErrorInvalidInstance(instance) }
if (callback != as!VkDebugReportCallbackEXT(0)) {
delete(DebugReportCallbacks, callback)
}
}

@extension("VK_EXT_debug_report")
Expand All @@ -185,3 +199,13 @@ cmd void vkDebugReportMessageEXT(
if !(instance in Instances) { vkErrorInvalidInstance(instance) }
}

////////////////////
// State tracking //
////////////////////

@internal class DebugReportCallbackObject {
@unused VkInstance Instance
@unused VkDebugReportFlagsEXT Flags
@unused VkDebugReportCallbackEXT VulkanHandle
}

22 changes: 15 additions & 7 deletions gapis/api/vulkan/find_issues.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,16 @@ func isValidationLayer(n string) bool {
// NOTE: right now this transform is just used to close chans passed in requests.
type findIssues struct {
state *api.GlobalState
numInitialCmds int
issues []replay.Issue
res []replay.Result
reportCallbacks map[VkInstance]VkDebugReportCallbackEXT
}

func newFindIssues(ctx context.Context, c *capture.Capture) *findIssues {
func newFindIssues(ctx context.Context, c *capture.Capture, numInitialCmds int) *findIssues {
t := &findIssues{
state: c.NewState(ctx),
state: c.NewState(ctx),
numInitialCmds: numInitialCmds,
}
t.state.OnError = func(err interface{}) {
if issue, ok := err.(replay.Issue); ok {
Expand Down Expand Up @@ -251,15 +253,21 @@ func (t *findIssues) Flush(ctx context.Context, out transform.Writer) {
b.RegisterNotificationReader(func(n gapir.Notification) {
vkApi := API{}
if uint8(n.GetApiIndex()) != vkApi.Index() {
log.W(ctx, "is not vulkan report: %v", n)
return
}
var issue replay.Issue
// TODO: For MEC, we need to minus the number of initial commands
// TODO: Figure out what to do for commands inserted by GAPID, whose label is ~0.
issue.Command = api.CmdID(n.GetLabel())
msg := n.GetMsg()
label := n.GetLabel()
if int(label) < t.numInitialCmds {
// The debug report is issued for state rebuilding command
issue.Command = api.CmdID(0)
issue.Error = fmt.Errorf("[State rebuilding command, linearized ID: %d]: %s", label, msg)
} else {
// The debug report is issued for a trace command
issue.Command = api.CmdID(label - uint64(t.numInitialCmds))
issue.Error = fmt.Errorf("%s", msg)
}
issue.Severity = service.Severity(uint32(n.GetSeverity()))
issue.Error = fmt.Errorf("%s", n.GetMsg())
t.issues = append(t.issues, issue)
})
// Since the PostBack function is called before the replay target has actually arrived at the post command,
Expand Down
55 changes: 35 additions & 20 deletions gapis/api/vulkan/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,11 @@ func (t *destroyResourcesAtEOS) Flush(ctx context.Context, out transform.Writer)
out.MutateAndWrite(ctx, id, cb.VkDestroySurfaceKHR(object.Instance(), handle, p))
}

// Debug report callbacks
for handle, object := range so.DebugReportCallbacks().All() {
out.MutateAndWrite(ctx, id, cb.ReplayDestroyVkDebugReportCallback(object.Instance(), handle))
}

// Instances.
for handle := range so.Instances().All() {
out.MutateAndWrite(ctx, id, cb.VkDestroyInstance(handle, p))
Expand Down Expand Up @@ -472,13 +477,18 @@ func (a API) Replay(
// we will need it.
dceInfo := dCEInfo{}

expandedCmds := false
numInitialCommands := 0
expandCommands := func() (int, error) {
if expandedCmds {
return numInitialCommands, nil
initCmdExpandedWithOpt := false
numInitialCmdWithOpt := 0
initCmdExpandedWithoutOpt := false
numInitialCmdWithoutOpt := 0
expandCommands := func(opt bool) (int, error) {
if opt && initCmdExpandedWithOpt {
return numInitialCmdWithOpt, nil
}
if optimize {
if !opt && initCmdExpandedWithoutOpt {
return numInitialCmdWithoutOpt, nil
}
if opt {
// If we have not set up the dependency graph, do it now.
if dceInfo.ft == nil {
ft, err := dependencygraph.GetFootprint(ctx)
Expand All @@ -489,18 +499,19 @@ func (a API) Replay(
dceInfo.dce = transform.NewDCE(ctx, dceInfo.ft)
}
cmds = []api.Cmd{}
numInitialCommands = dceInfo.ft.NumInitialCommands
} else {
// If the capture contains initial state, prepend the commands to build the state.
initialCmds, im, _ := initialcmds.InitialCommands(ctx, intent.Capture)
out.State().Allocator.ReserveRanges(im)
numInitialCommands = len(initialCmds)
if len(initialCmds) > 0 {
cmds = append(initialCmds, cmds...)
}
numInitialCmdWithOpt = dceInfo.ft.NumInitialCommands
initCmdExpandedWithOpt = true
return numInitialCmdWithOpt, nil
}
expandedCmds = true
return numInitialCommands, nil
// If the capture contains initial state, prepend the commands to build the state.
initialCmds, im, _ := initialcmds.InitialCommands(ctx, intent.Capture)
out.State().Allocator.ReserveRanges(im)
numInitialCmdWithoutOpt = len(initialCmds)
if len(initialCmds) > 0 {
cmds = append(initialCmds, cmds...)
}
initCmdExpandedWithoutOpt = true
return numInitialCmdWithoutOpt, nil
}

wire := false
Expand All @@ -509,7 +520,11 @@ func (a API) Replay(
switch req := rr.Request.(type) {
case issuesRequest:
if issues == nil {
issues = newFindIssues(ctx, capture)
n, err := expandCommands(false)
if err != nil {
return err
}
issues = newFindIssues(ctx, capture, n)
}
issues.reportTo(rr.Result)
optimize = false
Expand All @@ -520,7 +535,7 @@ func (a API) Replay(
if cfg.disableReplayOptimization {
optimize = false
}
extraCommands, err := expandCommands()
extraCommands, err := expandCommands(optimize)
if err != nil {
return err
}
Expand Down Expand Up @@ -560,7 +575,7 @@ func (a API) Replay(
}
}

_, err = expandCommands()
_, err = expandCommands(optimize)
if err != nil {
return err
}
Expand Down
18 changes: 15 additions & 3 deletions gapis/api/vulkan/synthetic.api
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,27 @@ cmd bool ReplayCreateVkDebugReportCallback(
VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
VkDebugReportCallbackEXT* pCallback) {

read(pCreateInfo[0:1])
if !(instance in Instances) { vkErrorInvalidInstance(instance) }
if pCreateInfo == null { vkErrorNullPointer("VkDebugReportCallbackCreateInfoEXT") }
info := pCreateInfo[0]
handle := ?
if pCallback == null { vkErrorNullPointer("VkDebugReportCallbackEXT") }
pCallback[0] = handle
object := new!DebugReportCallbackObject(
Instance: instance,
Flags: info.flags,
VulkanHandle: handle,
)
DebugReportCallbacks[handle] = object
return ?
}

@synthetic
cmd void ReplayDestroyVkDebugReportCallback(
VkInstance instance,
VkDebugReportCallbackEXT callback) { }
VkDebugReportCallbackEXT callback) {
if !(instance in Instances) { vkErrorInvalidInstance(instance) }
if (callback != as!VkDebugReportCallbackEXT(0)) {
delete(DebugReportCallbacks, callback)
}
}
49 changes: 25 additions & 24 deletions gapis/api/vulkan/vulkan.api
Original file line number Diff line number Diff line change
Expand Up @@ -274,30 +274,31 @@ enum LastSubmissionType {
@serialize map!(VkQueue, ref!QueueObject) Queues
@serialize map!(VkCommandBuffer, ref!CommandBufferObject) CommandBuffers
// Non-dispatchable objects.
@serialize map!(VkDeviceMemory, ref!DeviceMemoryObject) DeviceMemories
@serialize map!(VkBuffer, ref!BufferObject) Buffers
@serialize map!(VkBufferView, ref!BufferViewObject) BufferViews
@serialize map!(VkImage, ref!ImageObject) Images
@serialize map!(VkImageView, ref!ImageViewObject) ImageViews
@serialize map!(VkShaderModule, ref!ShaderModuleObject) ShaderModules
@serialize map!(VkPipeline, ref!GraphicsPipelineObject) GraphicsPipelines
@serialize map!(VkPipeline, ref!ComputePipelineObject) ComputePipelines
@serialize map!(VkPipelineLayout, ref!PipelineLayoutObject) PipelineLayouts
@serialize map!(VkSampler, ref!SamplerObject) Samplers
@serialize map!(VkDescriptorSet, ref!DescriptorSetObject) DescriptorSets
@serialize map!(VkDescriptorSetLayout, ref!DescriptorSetLayoutObject) DescriptorSetLayouts
@serialize map!(VkDescriptorPool, ref!DescriptorPoolObject) DescriptorPools
@serialize map!(VkFence, ref!FenceObject) Fences
@serialize map!(VkSemaphore, ref!SemaphoreObject) Semaphores
@serialize map!(VkEvent, ref!EventObject) Events
@serialize map!(VkQueryPool, ref!QueryPoolObject) QueryPools
@serialize map!(VkFramebuffer, ref!FramebufferObject) Framebuffers
@serialize map!(VkRenderPass, ref!RenderPassObject) RenderPasses
@serialize map!(VkPipelineCache, ref!PipelineCacheObject) PipelineCaches
@serialize map!(VkCommandPool, ref!CommandPoolObject) CommandPools
@serialize map!(VkSurfaceKHR, ref!SurfaceObject) Surfaces
@serialize map!(VkSwapchainKHR, ref!SwapchainObject) Swapchains
@serialize map!(VkDisplayModeKHR, ref!DisplayModeObject) DisplayModes
@serialize map!(VkDeviceMemory, ref!DeviceMemoryObject) DeviceMemories
@serialize map!(VkBuffer, ref!BufferObject) Buffers
@serialize map!(VkBufferView, ref!BufferViewObject) BufferViews
@serialize map!(VkImage, ref!ImageObject) Images
@serialize map!(VkImageView, ref!ImageViewObject) ImageViews
@serialize map!(VkShaderModule, ref!ShaderModuleObject) ShaderModules
@serialize map!(VkPipeline, ref!GraphicsPipelineObject) GraphicsPipelines
@serialize map!(VkPipeline, ref!ComputePipelineObject) ComputePipelines
@serialize map!(VkPipelineLayout, ref!PipelineLayoutObject) PipelineLayouts
@serialize map!(VkSampler, ref!SamplerObject) Samplers
@serialize map!(VkDescriptorSet, ref!DescriptorSetObject) DescriptorSets
@serialize map!(VkDescriptorSetLayout, ref!DescriptorSetLayoutObject) DescriptorSetLayouts
@serialize map!(VkDescriptorPool, ref!DescriptorPoolObject) DescriptorPools
@serialize map!(VkFence, ref!FenceObject) Fences
@serialize map!(VkSemaphore, ref!SemaphoreObject) Semaphores
@serialize map!(VkEvent, ref!EventObject) Events
@serialize map!(VkQueryPool, ref!QueryPoolObject) QueryPools
@serialize map!(VkFramebuffer, ref!FramebufferObject) Framebuffers
@serialize map!(VkRenderPass, ref!RenderPassObject) RenderPasses
@serialize map!(VkPipelineCache, ref!PipelineCacheObject) PipelineCaches
@serialize map!(VkCommandPool, ref!CommandPoolObject) CommandPools
@serialize map!(VkSurfaceKHR, ref!SurfaceObject) Surfaces
@serialize map!(VkSwapchainKHR, ref!SwapchainObject) Swapchains
@serialize map!(VkDisplayModeKHR, ref!DisplayModeObject) DisplayModes
@serialize map!(VkDebugReportCallbackEXT, ref!DebugReportCallbackObject) DebugReportCallbacks
// Other state Tracking
@hidden @serialize map!(VkDevice, VkMemoryRequirements) TransferBufferMemoryRequirements
@serialize ref!QueueObject LastBoundQueue
Expand Down

0 comments on commit 17b5ac2

Please sign in to comment.