Skip to content

Commit

Permalink
Update to read_framebuffer to allow compute presentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
AWoloszyn committed Apr 24, 2018
1 parent 796bbe9 commit 5c39b3e
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 78 deletions.
2 changes: 1 addition & 1 deletion gapis/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type API interface {
after []uint64,
state *GlobalState,
thread uint64,
attachment FramebufferAttachment) (width, height, index uint32, format *image.Format, err error)
attachment FramebufferAttachment) (width, height, index uint32, format *image.Format, canResize bool, err error)

// Context returns the active context for the given state.
Context(state *GlobalState, thread uint64) Context
Expand Down
18 changes: 9 additions & 9 deletions gapis/api/gles/gles.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (API) GetFramebufferAttachmentInfo(
after []uint64,
state *api.GlobalState,
thread uint64,
attachment api.FramebufferAttachment) (width, height, index uint32, format *image.Format, err error) {
attachment api.FramebufferAttachment) (width, height, index uint32, format *image.Format, canResize bool, err error) {

return GetFramebufferAttachmentInfoByID(state, thread, attachment, 0)
}
Expand All @@ -205,45 +205,45 @@ func GetFramebufferAttachmentInfoByID(
state *api.GlobalState,
thread uint64,
attachment api.FramebufferAttachment,
fb FramebufferId) (width, height, index uint32, format *image.Format, err error) {
fb FramebufferId) (width, height, index uint32, format *image.Format, canResize bool, err error) {

s := GetState(state)

if fb == 0 {
c := s.GetContext(thread)
if c == nil {
return 0, 0, 0, nil, fmt.Errorf("No context bound")
return 0, 0, 0, nil, true, fmt.Errorf("No context bound")
}
if !c.Other.Initialized {
return 0, 0, 0, nil, fmt.Errorf("Context not initialized")
return 0, 0, 0, nil, true, fmt.Errorf("Context not initialized")
}
fb = c.Bound.DrawFramebuffer.GetID()
}

glAtt, err := attachmentToEnum(attachment)
if err != nil {
return 0, 0, 0, nil, err
return 0, 0, 0, nil, true, err
}

fbai, err := s.getFramebufferAttachmentInfo(thread, fb, glAtt)
if fbai.format == 0 {
return 0, 0, 0, nil, fmt.Errorf("No format set")
return 0, 0, 0, nil, true, fmt.Errorf("No format set")
}
if err != nil {
return 0, 0, 0, nil, err
return 0, 0, 0, nil, true, err
}
fmt, ty := getUnsizedFormatAndType(fbai.format)
f, err := getImageFormat(fmt, ty)
if err != nil {
return 0, 0, 0, nil, err
return 0, 0, 0, nil, true, err
}
switch {
case attachment.IsDepth():
f = filterUncompressedImageFormat(f, stream.Channel.IsDepth)
case attachment.IsStencil():
f = filterUncompressedImageFormat(f, stream.Channel.IsStencil)
}
return fbai.width, fbai.height, 0, f, nil
return fbai.width, fbai.height, 0, f, true, nil
}

// Context returns the active context for the given state and thread.
Expand Down
4 changes: 2 additions & 2 deletions gapis/api/gvr/gvr.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ func (API) GetFramebufferAttachmentInfo(
after []uint64,
state *api.GlobalState,
thread uint64,
attachment api.FramebufferAttachment) (width, height, index uint32, format *image.Format, err error) {
attachment api.FramebufferAttachment) (width, height, index uint32, format *image.Format, canResize bool, err error) {

fb, err := getFramebuffer(ctx, api.CmdID(after[0]))
if err != nil {
return 0, 0, 0, nil, err
return 0, 0, 0, nil, false, err
}
return gles.GetFramebufferAttachmentInfoByID(state, thread, attachment, fb)
}
Expand Down
120 changes: 74 additions & 46 deletions gapis/api/vulkan/read_framebuffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ func postImageData(ctx context.Context,
device := GetState(s).Devices.Get(vkDevice)
vkPhysicalDevice := device.PhysicalDevice
physicalDevice := GetState(s).PhysicalDevices.Get(vkPhysicalDevice)

requestWidth := reqWidth
requestHeight := reqHeight

// Rendered image should always has a graphics-capable queue bound, if none
// of such a queue found for this image or the bound queue does not have
// graphics capability, throw error messages and return.
Expand All @@ -228,8 +232,17 @@ func postImageData(ctx context.Context,
}
if properties, ok := physicalDevice.QueueFamilyProperties.Lookup(queue.Family); ok {
if properties.QueueFlags&VkQueueFlags(VkQueueFlagBits_VK_QUEUE_GRAPHICS_BIT) == 0 {
res(nil, &service.ErrDataUnavailable{Reason: messages.ErrMessage("The bound vkQueue does not have VK_QUEUE_GRAPHICS_BIT capability")})
return
if imageObject.Info.Samples == VkSampleCountFlagBits_VK_SAMPLE_COUNT_1_BIT &&
aspect == VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT {
// If this is on the compute queue, we cannot do a blit operation,
// We can however do it on the CPU afterwards, or let the
// client deal with it
requestWidth = imgWidth
requestHeight = imgHeight
} else {
res(nil, &service.ErrDataUnavailable{Reason: messages.ErrMessage("Unhandled: Reading a multisampled or depth image on the compute queue")})
return
}
}
} else {
res(nil, &service.ErrDataUnavailable{Reason: messages.ErrMessage("Not found the properties information of the bound vkQueue")})
Expand Down Expand Up @@ -273,13 +286,13 @@ func postImageData(ctx context.Context,
}
}

bufferSize := uint64(formatOfImgRes.Size(int(reqWidth), int(reqHeight), 1))
bufferSize := uint64(formatOfImgRes.Size(int(requestWidth), int(requestHeight), 1))
// For the depth aspect of VK_FORMAT_X8_D24_UNORM_PACK32 and
// VK_FORMAT_D24_UNORM_S8_UINT format, each depth element requires 4 bytes in
// the buffer when used in buffer image copy.
if aspect == VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT && (vkFormat == VkFormat_VK_FORMAT_X8_D24_UNORM_PACK32 || vkFormat == VkFormat_VK_FORMAT_D24_UNORM_S8_UINT) {
r32Fmt, _ := getImageFormatFromVulkanFormat(VkFormat_VK_FORMAT_R32_UINT)
bufferSize = uint64(r32Fmt.Size(int(reqWidth), int(reqHeight), 1))
bufferSize = uint64(r32Fmt.Size(int(requestWidth), int(requestHeight), 1))
}

// Data and info for destination buffer creation
Expand Down Expand Up @@ -315,8 +328,8 @@ func postImageData(ctx context.Context,
ImageType: VkImageType_VK_IMAGE_TYPE_2D,
Fmt: vkFormat,
Extent: VkExtent3D{
Width: reqWidth,
Height: reqHeight,
Width: requestWidth,
Height: requestHeight,
Depth: 1,
},
MipLevels: 1,
Expand Down Expand Up @@ -413,7 +426,7 @@ func postImageData(ctx context.Context,
LayerCount: 1,
},
ImageOffset: VkOffset3D{X: 0, Y: 0, Z: 0},
ImageExtent: VkExtent3D{Width: reqWidth, Height: reqHeight, Depth: 1},
ImageExtent: VkExtent3D{Width: requestWidth, Height: requestHeight, Depth: 1},
}
bufferImageCopyData := MustAllocData(ctx, s, bufferImageCopy)

Expand Down Expand Up @@ -629,8 +642,8 @@ func postImageData(ctx context.Context,
Z: 0,
},
{
X: int32(reqWidth),
Y: int32(reqHeight),
X: int32(requestWidth),
Y: int32(requestHeight),
Z: 1,
},
},
Expand Down Expand Up @@ -906,36 +919,60 @@ func postImageData(ctx context.Context,
if aspect != VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT {
filter = VkFilter_VK_FILTER_NEAREST
}

doBlit := true
copySrc := stagingImageId

if requestWidth == imgWidth && requestHeight == imgHeight {
doBlit = false
copySrc = blitSrcImage
}

if doBlit {
writeEach(ctx, out,
cb.VkCmdBlitImage(
commandBufferId,
blitSrcImage,
VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
stagingImageId,
VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
imageBlitData.Ptr(),
filter,
).AddRead(imageBlitData.Data()),
// Set the blit image to transfer src
cb.VkCmdPipelineBarrier(
commandBufferId,
VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT),
VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT),
VkDependencyFlags(0),
0,
memory.Nullptr,
0,
memory.Nullptr,
1,
stagingImageToSrcBarrierData.Ptr(),
).AddRead(
stagingImageToSrcBarrierData.Data(),
),
)
}

writeEach(ctx, out,
cb.VkCmdBlitImage(
cb.VkCmdCopyImageToBuffer(
commandBufferId,
blitSrcImage,
copySrc,
VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
stagingImageId,
VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
bufferId,
1,
imageBlitData.Ptr(),
filter,
).AddRead(imageBlitData.Data()),
bufferImageCopyData.Ptr(),
).AddRead(
bufferImageCopyData.Data(),
),
)

// Change the layout of staging image and attachment image, copy staging image to buffer,
// end command buffer
writeEach(ctx, out,
cb.VkCmdPipelineBarrier(
commandBufferId,
VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT),
VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT),
VkDependencyFlags(0),
0,
memory.Nullptr,
0,
memory.Nullptr,
1,
stagingImageToSrcBarrierData.Ptr(),
).AddRead(
stagingImageToSrcBarrierData.Data(),
),
// Reset the image, and end the command buffer.
cb.VkCmdPipelineBarrier(
commandBufferId,
VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT),
Expand All @@ -950,20 +987,11 @@ func postImageData(ctx context.Context,
).AddRead(
attachmentImageResetLayoutBarrierData.Data(),
),
cb.VkCmdCopyImageToBuffer(
commandBufferId,
stagingImageId,
VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
bufferId,
1,
bufferImageCopyData.Ptr(),
).AddRead(
bufferImageCopyData.Data(),
),
cb.VkEndCommandBuffer(
commandBufferId,
VkResult_VK_SUCCESS,
))
),
)

// Submit all the commands above, wait until finish.
writeEach(ctx, out,
Expand Down Expand Up @@ -1036,7 +1064,7 @@ func postImageData(ctx context.Context,
}

// Flip the image in Y axis
rowSizeInBytes := uint64(formatOfImgRes.Size(int(reqWidth), 1, 1))
rowSizeInBytes := uint64(formatOfImgRes.Size(int(requestWidth), 1, 1))
top := uint64(0)
bottom := bufferSize - rowSizeInBytes
var temp = make([]byte, rowSizeInBytes)
Expand All @@ -1055,8 +1083,8 @@ func postImageData(ctx context.Context,

img := &image.Data{
Bytes: bytes,
Width: uint32(reqWidth),
Height: uint32(reqHeight),
Width: uint32(requestWidth),
Height: uint32(requestHeight),
Depth: 1,
Format: formatOfImgRes,
}
Expand Down
32 changes: 22 additions & 10 deletions gapis/api/vulkan/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import (
"github.com/google/gapid/gapis/api"
)

func (st *State) getSubmitAttachmentInfo(attachment api.FramebufferAttachment) (w, h uint32, f VkFormat, attachmentIndex uint32, err error) {
returnError := func(format_str string, e ...interface{}) (w, h uint32, f VkFormat, attachmentIndex uint32, err error) {
return 0, 0, VkFormat_VK_FORMAT_UNDEFINED, 0, fmt.Errorf(format_str, e...)
func (st *State) getSubmitAttachmentInfo(attachment api.FramebufferAttachment) (w, h uint32, f VkFormat, attachmentIndex uint32, canResize bool, err error) {
returnError := func(format_str string, e ...interface{}) (w, h uint32, f VkFormat, attachmentIndex uint32, canResize bool, err error) {
return 0, 0, VkFormat_VK_FORMAT_UNDEFINED, 0, true, fmt.Errorf(format_str, e...)
}

lastQueue := st.LastBoundQueue
Expand Down Expand Up @@ -54,7 +54,7 @@ func (st *State) getSubmitAttachmentInfo(attachment api.FramebufferAttachment) (
attachment_index := uint32(attachment - api.FramebufferAttachment_Color0)
if att_ref, ok := subpass_desc.ColorAttachments.Lookup(attachment_index); ok {
if ca, ok := lastDrawInfo.Framebuffer.ImageAttachments.Lookup(att_ref.Attachment); ok {
return ca.Image.Info.Extent.Width, ca.Image.Info.Extent.Height, ca.Image.Info.Fmt, att_ref.Attachment, nil
return ca.Image.Info.Extent.Width, ca.Image.Info.Extent.Height, ca.Image.Info.Fmt, att_ref.Attachment, true, nil
}

}
Expand All @@ -63,7 +63,7 @@ func (st *State) getSubmitAttachmentInfo(attachment api.FramebufferAttachment) (
att_ref := subpass_desc.DepthStencilAttachment
if attachment, ok := lastDrawInfo.Framebuffer.ImageAttachments.Lookup(att_ref.Attachment); ok {
depth_img := attachment.Image
return depth_img.Info.Extent.Width, depth_img.Info.Extent.Height, depth_img.Info.Fmt, att_ref.Attachment, nil
return depth_img.Info.Extent.Width, depth_img.Info.Extent.Height, depth_img.Info.Fmt, att_ref.Attachment, true, nil
}
}
case api.FramebufferAttachment_Stencil:
Expand All @@ -75,9 +75,9 @@ func (st *State) getSubmitAttachmentInfo(attachment api.FramebufferAttachment) (
return returnError("%s is not bound", attachment)
}

func (st *State) getPresentAttachmentInfo(attachment api.FramebufferAttachment) (w, h uint32, f VkFormat, attachmentIndex uint32, err error) {
returnError := func(format_str string, e ...interface{}) (w, h uint32, f VkFormat, attachmentIndex uint32, err error) {
return 0, 0, VkFormat_VK_FORMAT_UNDEFINED, 0, fmt.Errorf(format_str, e...)
func (st *State) getPresentAttachmentInfo(attachment api.FramebufferAttachment) (w, h uint32, f VkFormat, attachmentIndex uint32, canResize bool, err error) {
returnError := func(format_str string, e ...interface{}) (w, h uint32, f VkFormat, attachmentIndex uint32, canResize bool, err error) {
return 0, 0, VkFormat_VK_FORMAT_UNDEFINED, 0, false, fmt.Errorf(format_str, e...)
}

switch attachment {
Expand All @@ -91,7 +91,19 @@ func (st *State) getPresentAttachmentInfo(attachment api.FramebufferAttachment)
}
color_img := st.LastPresentInfo.PresentImages.Get(image_idx)
if color_img != nil {
return color_img.Info.Extent.Width, color_img.Info.Extent.Height, color_img.Info.Fmt, image_idx, nil
queue := color_img.LastBoundQueue
vkDevice := queue.Device
device := st.Devices.Get(vkDevice)
vkPhysicalDevice := device.PhysicalDevice
physicalDevice := st.PhysicalDevices.Get(vkPhysicalDevice)
if properties, ok := physicalDevice.QueueFamilyProperties.Lookup(queue.Family); ok {
if properties.QueueFlags&VkQueueFlags(VkQueueFlagBits_VK_QUEUE_GRAPHICS_BIT) != 0 {
return color_img.Info.Extent.Width, color_img.Info.Extent.Height, color_img.Info.Fmt, image_idx, true, nil
}
return color_img.Info.Extent.Width, color_img.Info.Extent.Height, color_img.Info.Fmt, image_idx, false, nil
}

return returnError("Last present queue does not exist", attachment)
}
case api.FramebufferAttachment_Depth:
fallthrough
Expand All @@ -103,7 +115,7 @@ func (st *State) getPresentAttachmentInfo(attachment api.FramebufferAttachment)
return returnError("Swapchain attachment %v does not exist", attachment)
}

func (st *State) getFramebufferAttachmentInfo(attachment api.FramebufferAttachment) (uint32, uint32, VkFormat, uint32, error) {
func (st *State) getFramebufferAttachmentInfo(attachment api.FramebufferAttachment) (uint32, uint32, VkFormat, uint32, bool, error) {
if st.LastSubmission == LastSubmissionType_SUBMIT {
return st.getSubmitAttachmentInfo(attachment)
} else {
Expand Down
14 changes: 7 additions & 7 deletions gapis/api/vulkan/vulkan.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,24 @@ func (API) GetFramebufferAttachmentInfo(
after []uint64,
state *api.GlobalState,
thread uint64,
attachment api.FramebufferAttachment) (width, height, index uint32, format *image.Format, err error) {
attachment api.FramebufferAttachment) (width, height, index uint32, format *image.Format, canResize bool, err error) {

w, h, form, i, err := GetState(state).getFramebufferAttachmentInfo(attachment)
w, h, form, i, r, err := GetState(state).getFramebufferAttachmentInfo(attachment)
switch attachment {
case api.FramebufferAttachment_Stencil:
return 0, 0, 0, nil, fmt.Errorf("Unsupported Stencil")
return 0, 0, 0, nil, true, fmt.Errorf("Unsupported Stencil")
case api.FramebufferAttachment_Depth:
format, err := getDepthImageFormatFromVulkanFormat(form)
if err != nil {
return 0, 0, 0, nil, fmt.Errorf("Unknown format for Depth attachment: %v", form)
return 0, 0, 0, nil, true, fmt.Errorf("Unknown format for Depth attachment: %v", form)
}
return w, h, i, format, err
return w, h, i, format, r, err
default:
format, err := getImageFormatFromVulkanFormat(form)
if err != nil {
return 0, 0, 0, nil, fmt.Errorf("Unknown format for Color attachment: %v", form)
return 0, 0, 0, nil, true, fmt.Errorf("Unknown format for Color attachment: %v", form)
}
return w, h, i, format, err
return w, h, i, format, r, err
}
}

Expand Down
Loading

0 comments on commit 5c39b3e

Please sign in to comment.