Permalink
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...
1 parent 3d47062 commit 07b64e28965a4b0204bef4e1712fbac3cb190008 matsi committed Sep 9, 2012
Showing with 308 additions and 69 deletions.
  1. +15 −2 CMakeLists.txt
  2. +3 −67 drm_dumb_bo.c
  3. +182 −0 drm_dumb_bo_libkms.c
  4. +80 −0 drm_utils.c
  5. +28 −0 drm_utils.h
View
@@ -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
@@ -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
@@ -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
@@ -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;
+}
Oops, something went wrong.

0 comments on commit 07b64e2

Please sign in to comment.