Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Yet another example and minor reorganization of code.

1. Move find_drm_configuration function to a separate file

2. Add example: drm_dumb_bo_libkms.c
   Basically this example does the same as drm_dumb_bo.c. But this example uses libkms to
   create and configure dumb buffer object instead of direct calls of drmIoctl.
  • Loading branch information...
commit 07b64e28965a4b0204bef4e1712fbac3cb190008 1 parent 3d47062
matsi authored
View
17 CMakeLists.txt
@@ -3,7 +3,8 @@ project(drm_tests)
add_executable(test test.c)
add_executable(drm_info drm_info.c)
-add_executable(drm_dumb_bo drm_dumb_bo.c)
+add_executable(drm_dumb_bo drm_dumb_bo.c drm_utils.c)
+add_executable(drm_dumb_bo_libkms drm_dumb_bo_libkms.c drm_utils.c)
# find headers
@@ -27,6 +28,11 @@ NAMES gbm.h
PATHS /usr/include /usr/local/include
)
+FIND_PATH(KMS_INCLUDE_DIR
+NAMES libkms.h
+PATHS /usr/include/libkms /usr/local/include/libkms
+)
+
# find libraries
FIND_LIBRARY(GL_LIBRARY
@@ -49,15 +55,22 @@ NAMES gbm
PATHS /usr/lib /usr/local/lib
)
+FIND_LIBRARY(KMS_LIBRARY
+NAMES kms
+PATHS /usr/lib /usr/lib/i386-linux/gnu
+)
+
# set headers paths
include_directories(${EGL_INCLUDE_DIR})
include_directories(${DRM_INCLUDE_DIR})
include_directories(${GBM_INCLUDE_DIR})
+include_directories(${KMS_INCLUDE_DIR})
include_directories(${GL_INCLUDE_DIR})
# set libraries paths
target_link_libraries(test ${EGL_LIBRARY} ${DRM_LIBRARY} ${GBM_LIBRARY} ${GL_LIBRARY})
-target_link_libraries(drm_info ${DRM_LIBRARY} ${GBM_LIBRARY})
+target_link_libraries(drm_info ${DRM_LIBRARY} ${GBM_LIBRARY} ${GL_LIBRARY})
target_link_libraries(drm_dumb_bo ${DRM_LIBRARY})
+target_link_libraries(drm_dumb_bo_libkms ${KMS_LIBRARY})
View
70 drm_dumb_bo.c
@@ -15,13 +15,9 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
-/* */
+#include "drm_utils.h"
-struct kms {
- drmModeConnector *connector;
- drmModeEncoder *encoder;
- drmModeModeInfo mode;
-};
+/* */
struct dumb_rb {
uint32_t fb;
@@ -37,69 +33,9 @@ static const char device_name[] = "/dev/dri/card0";
/* */
-bool find_drm_configuration(int fd, struct kms *kms)
-{
- drmModeConnector *connector;
- drmModeEncoder *encoder;
- drmModeRes *resources;
-
- int i;
-
- resources = drmModeGetResources(fd);
- if (!resources) {
- fprintf(stderr, "drmModeGetResources failed\n");
- return false;
- }
-
- for (i = 0; i < resources->count_connectors; i++) {
- connector = drmModeGetConnector(fd, resources->connectors[i]);
- if (connector == NULL)
- continue;
-
- if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0)
- break;
-
- drmModeFreeConnector(connector);
- }
-
- if (i == resources->count_connectors) {
- fprintf(stderr, "No currently active connector found\n");
- return false;
- }
-
- for (i = 0; i < resources->count_encoders; i++) {
- encoder = drmModeGetEncoder(fd, resources->encoders[i]);
-
- if (encoder == NULL)
- continue;
-
- if (encoder->encoder_id == connector->encoder_id)
- break;
-
- drmModeFreeEncoder(encoder);
- }
-
- if (i == resources->count_encoders) {
- fprintf(stderr, "No matching encoder for connector found\n");
- goto drm_free_connector;
- }
-
-
- kms->connector = connector;
- kms->encoder = encoder;
- kms->mode = connector->modes[0];
-
- return true;
-
-drm_free_connector:
- drmModeFreeConnector(connector);
-
- return false;
-}
-
int main(char argc, char *argv[])
{
- struct kms kms_data;
+ struct kms_display kms_data;
struct dumb_rb dbo;
uint64_t has_dumb;
int ret, fd;
View
182 drm_dumb_bo_libkms.c
@@ -0,0 +1,182 @@
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+
+#include <xf86drmMode.h>
+#include <xf86drm.h>
+#include <libkms.h>
+
+#include "drm_utils.h"
+
+/* */
+
+static const char device_name[] = "/dev/dri/card0";
+
+/* */
+
+int main(char argc, char *argv[])
+{
+ struct kms_driver *drv;
+ struct kms_bo *bo;
+
+ struct kms_display kms_data;
+
+ uint32_t fb, stride, handle;
+ uint32_t *dst;
+ int ret, fd;
+
+ drmModeCrtcPtr saved_crtc;
+
+ uint32_t attr[] = {
+ KMS_WIDTH, 0,
+ KMS_HEIGHT, 0,
+ KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8,
+ KMS_TERMINATE_PROP_LIST, 0
+ };
+
+ fd = open(device_name, O_RDWR | O_CLOEXEC);
+ if (fd < 0) {
+ perror("cannot open drm device");
+ exit(-1);
+ }
+
+ /* find current DRM configuration */
+
+ if (!find_drm_configuration(fd, &kms_data)) {
+ fprintf(stderr, "failed to setup KMS\n");
+ ret = -EFAULT;
+ goto err_close;
+ }
+
+ /* set display dimensions for chosen configuration */
+
+ attr[1] = kms_data.mode.hdisplay;
+ attr[3] = kms_data.mode.vdisplay;
+
+ /* create kms driver */
+
+ ret = kms_create(fd, &drv);
+ if (ret) {
+ fprintf(stderr, "failed to setup kms driver\n");
+ goto err_close;
+ }
+
+ /* create dumb buffer object */
+
+ ret = kms_bo_create(drv, attr, &bo);
+ if (ret) {
+ fprintf(stderr, "failed to create dumb bo\n");
+ goto err_driver_destroy;
+ }
+
+ ret = kms_bo_get_prop(bo, KMS_PITCH, &stride);
+ if (ret) {
+ fprintf(stderr, "failed to get attrs of dumb bo\n");
+ goto err_buffer_destroy;
+ }
+
+ ret = kms_bo_get_prop(bo, KMS_HANDLE, &handle);
+ if (ret) {
+ fprintf(stderr, "failed to get attrs of dumb bo\n");
+ goto err_buffer_destroy;
+ }
+
+ /* map dumb buffer object */
+
+ ret = kms_bo_map(bo, (void **) &dst);
+ if (ret) {
+ fprintf(stderr, "failed to map buffer object\n");
+ goto err_buffer_destroy;
+ }
+
+ /* create drm framebuffer */
+
+ ret = drmModeAddFB(fd, kms_data.mode.hdisplay, kms_data.mode.vdisplay, 24, 32, stride, handle, &fb);
+ if (ret) {
+ fprintf(stderr, "cannot add drm framebuffer for dumb buffer object\n");
+ goto err_buffer_unmap;
+ }
+
+ /* store current crtc */
+
+ saved_crtc = drmModeGetCrtc(fd, kms_data.encoder->crtc_id);
+ if (saved_crtc == NULL) {
+ fprintf(stderr, "failed to get current mode\n");
+ goto err_buffer_unmap;
+ }
+
+ /* setup new crtc */
+
+ ret = drmModeSetCrtc(fd, kms_data.encoder->crtc_id, fb, 0, 0,
+ &kms_data.connector->connector_id, 1, &kms_data.mode);
+ if (ret) {
+ fprintf(stderr, "cannot set new drm crtc");
+ goto err_buffer_unmap;
+ }
+
+ /* draw on the screen */
+
+ do {
+
+ uint32_t color32[] = {
+ 0x000000FF, 0x0000FF00, 0x00FF0000,
+ 0x00FF00FF, 0x00FFFF00, 0x0000FFFF,
+ };
+
+ uint32_t h = kms_data.mode.vdisplay;
+ uint32_t w = kms_data.mode.hdisplay;
+ uint32_t color;
+ int i, j;
+
+ for(i = 0; i < h; i++ ){
+
+ color = color32[6*i/h];
+
+ for(j = 0; j < w; j++) {
+ *(dst + i*w + j) = color;
+ }
+ }
+
+ getchar();
+
+ } while(0);
+
+ ret = drmModeSetCrtc(fd, saved_crtc->crtc_id, saved_crtc->buffer_id,
+ saved_crtc->x, saved_crtc->y, &kms_data.connector->connector_id, 1, &saved_crtc->mode);
+
+err_fb:
+ drmModeRmFB(fd, fb);
+
+err_buffer_unmap:
+ ret = kms_bo_unmap(bo);
+ if (ret) {
+ fprintf(stderr, "cannot unmap dumb buffer");
+ }
+
+err_buffer_destroy:
+ ret = kms_bo_destroy(&bo);
+ if (ret) {
+ fprintf(stderr, "cannot destroy dumb buffer");
+ }
+
+err_driver_destroy:
+ ret = kms_destroy(&drv);
+ if (ret) {
+ fprintf(stderr, "cannot destroy kms driver");
+ }
+
+err_close:
+ close(fd);
+
+ return ret;
+}
View
80 drm_utils.c
@@ -0,0 +1,80 @@
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include "drm_utils.h"
+
+/* */
+
+bool find_drm_configuration(int fd, struct kms_display *kms)
+{
+ drmModeConnector *connector;
+ drmModeEncoder *encoder;
+ drmModeRes *resources;
+
+ int i;
+
+ resources = drmModeGetResources(fd);
+ if (!resources) {
+ fprintf(stderr, "drmModeGetResources failed\n");
+ return false;
+ }
+
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = drmModeGetConnector(fd, resources->connectors[i]);
+ if (connector == NULL)
+ continue;
+
+ if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0)
+ break;
+
+ drmModeFreeConnector(connector);
+ }
+
+ if (i == resources->count_connectors) {
+ fprintf(stderr, "No currently active connector found\n");
+ return false;
+ }
+
+ for (i = 0; i < resources->count_encoders; i++) {
+ encoder = drmModeGetEncoder(fd, resources->encoders[i]);
+
+ if (encoder == NULL)
+ continue;
+
+ if (encoder->encoder_id == connector->encoder_id)
+ break;
+
+ drmModeFreeEncoder(encoder);
+ }
+
+ if (i == resources->count_encoders) {
+ fprintf(stderr, "No matching encoder for connector found\n");
+ goto drm_free_connector;
+ }
+
+
+ kms->connector = connector;
+ kms->encoder = encoder;
+ kms->mode = connector->modes[0];
+
+ return true;
+
+drm_free_connector:
+ drmModeFreeConnector(connector);
+
+ return false;
+}
View
28 drm_utils.h
@@ -0,0 +1,28 @@
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+/* */
+
+struct kms_display {
+ drmModeConnector *connector;
+ drmModeEncoder *encoder;
+ drmModeModeInfo mode;
+};
+
+/* */
+
+bool find_drm_configuration(int fd, struct kms_display *kms);
Please sign in to comment.
Something went wrong with that request. Please try again.