~sircmpwn/xrgears

ref: 1357a7691f8d6c04ac96499740f8db714a8bb54f xrgears/vkc/vkcSwapChainDRM.hpp -rw-r--r-- 3.1 KiB
1357a769 — Lubosz Sarnecki rename Swapchain to SwapChain 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#pragma once

#include <gbm.h>
#include <vulkan/vulkan_intel.h>

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include <poll.h>
#include <signal.h>

#include <gbm.h>

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <drm_fourcc.h>

#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>

#include <linux/kd.h>
#include <linux/vt.h>
#include <linux/major.h>

#include "vikSwapChain.hpp"

namespace vkc {

struct kms_buffer {
  gbm_bo *gbm_buffer;
  VkDeviceMemory mem;
  uint32_t fb;
  uint32_t stride;
};

class SwapChainDRM : public vik::SwapChain {

public:
  kms_buffer kms_buffers[MAX_NUM_IMAGES];
  int current;

  SwapChainDRM() {
  }

  ~SwapChainDRM() {
  }

  void init(VkDevice device, VkFormat image_format, gbm_device *gbm_dev, int fd,
            uint32_t width, uint32_t height, VkRenderPass render_pass) {
    PFN_vkCreateDmaBufImageINTEL create_dma_buf_image =
        (PFN_vkCreateDmaBufImageINTEL)vkGetDeviceProcAddr(device, "vkCreateDmaBufImageINTEL");

    for (uint32_t i = 0; i < 2; i++) {
      struct vik::RenderBuffer *b = &buffers[i];
      struct kms_buffer *kms_b = &kms_buffers[i];
      int buffer_fd, stride, ret;

      kms_b->gbm_buffer = gbm_bo_create(gbm_dev, width, height,
                                        GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT);

      buffer_fd = gbm_bo_get_fd(kms_b->gbm_buffer);
      stride = gbm_bo_get_stride(kms_b->gbm_buffer);


      VkDmaBufImageCreateInfo dmaBufInfo = {};

      VkExtent3D extent = {};
      extent.width = width;
      extent.height = height;
      extent.depth = 1;

      dmaBufInfo.sType = (VkStructureType) VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL;
      dmaBufInfo.fd = buffer_fd;
      dmaBufInfo.format = image_format;
      dmaBufInfo.extent = extent;
      dmaBufInfo.strideInBytes = stride;

      create_dma_buf_image(device,
                           &dmaBufInfo,
                           NULL,
                           &kms_b->mem,
                           &b->image);
      close(buffer_fd);

      kms_b->stride = gbm_bo_get_stride(kms_b->gbm_buffer);
      uint32_t bo_handles[4] = { (uint32_t) (gbm_bo_get_handle(kms_b->gbm_buffer).s32), };
      uint32_t pitches[4] = { (uint32_t) stride, };
      uint32_t offsets[4] = { 0, };
      ret = drmModeAddFB2(fd, width, height,
                          DRM_FORMAT_XRGB8888, bo_handles,
                          pitches, offsets, &kms_b->fb, 0);
      vik_log_f_if(ret == -1, "addfb2 failed");

      create_image_view(device, b->image,
                        image_format, &b->view);
      create_frame_buffer(device, render_pass, &b->view,
                          width, height, &b->framebuffer);
    }
  }

  void set_mode_and_page_flip(int fd, drmModeCrtc *crtc, drmModeConnector *connector) {
    int ret = drmModeSetCrtc(fd, crtc->crtc_id, kms_buffers[0].fb,
        0, 0, &connector->connector_id, 1, &crtc->mode);
    vik_log_f_if(ret < 0, "modeset failed: %m");

    ret = drmModePageFlip(fd, crtc->crtc_id, kms_buffers[0].fb,
        DRM_MODE_PAGE_FLIP_EVENT, NULL);
    vik_log_f_if(ret < 0, "pageflip failed: %m");
  }

};
}