Quellcode durchsuchen

Initial commit

main
Brian Ho vor 2 Jahren
Commit
6c993c5c25
4 geänderte Dateien mit 350 neuen und 0 gelöschten Zeilen
  1. 31
    0
      Makefile
  2. 295
    0
      dma_import.cc
  3. 12
    0
      dma_import.frag
  4. 12
    0
      dma_import.vert

+ 31
- 0
Makefile Datei anzeigen

@@ -0,0 +1,31 @@
SUBDIR = dma-import-gl
NAME = dma_import
CFLAGS = -std=c++17 --sysroot="$(SYSROOT)" -Wall
LDFLAGS = -lEGL -lGLESv2 -lgbm

CXX = /usr/bin/x86_64-cros-linux-gnu-clang++
CC = /usr/bin/x86_64-cros-linux-gnu-clang
SYSROOT = /build/volteer
SSH_DUT = dut
TARGET = volteer

all: build deploy run

build:
@echo Building...
@$(CXX) $(CFLAGS) -o ${NAME} ${NAME}.cc $(LDFLAGS)

deploy:
@echo Deploying to $(SSH_DUT)...
@scp ${NAME}.vert $(SSH_DUT):~/${SUBDIR}/${NAME}.vert
@scp ${NAME}.frag $(SSH_DUT):~/${SUBDIR}/${NAME}.frag
@scp ${NAME} $(SSH_DUT):~/${SUBDIR}/

run:
@echo Running on $(SSH_DUT)...
@ssh -tt $(SSH_DUT) 'cd ~/${SUBDIR} && ./${NAME}'

clean:
@rm -f ${NAME}
@ssh $(SSH_DUT) 'rm -f ~/${SUBDIR}/${NAME} ~/${SUBDIR}/${NAME}.vert \
~/${SUBDIR}/${NAME}.frag'

+ 295
- 0
dma_import.cc Datei anzeigen

@@ -0,0 +1,295 @@
#include <gbm.h>
#include <libdrm/drm_fourcc.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES3/gl32.h>

#include <array>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <linux/dma-buf.h>
#include <sstream>
#include <string>
#include <sys/ioctl.h>
#include <unistd.h>

const uint32_t kWidth = 1024;
const uint32_t kHeight = 1024;
const uint64_t kFramebufferModifier = I915_FORMAT_MOD_Y_TILED;
const uint64_t kTextureModifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS;
const std::string kVertexShaderPath = "dma_import.vert";
const std::string kFragmentShaderPath = "dma_import.frag";

struct Vertex {
float position[3];
float color[3];
};

EGLDisplay display;
EGLContext context;

#define ERROR(message) \
std::cerr << message << std::endl; \
std::exit(EXIT_FAILURE)

void InitializeEGL() {
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, nullptr, nullptr);
eglBindAPI(EGL_OPENGL_ES_API);

const EGLint config_attribs[] = {
EGL_SURFACE_TYPE, EGL_DONT_CARE,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE };
EGLConfig egl_config;
EGLint num_configs;
if (!eglChooseConfig(display, config_attribs, &egl_config, 1, &num_configs)) {
ERROR("Unable to choose EGL config");
}

const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
context = eglCreateContext(display, egl_config, EGL_NO_CONTEXT, context_attribs);
if (context == EGL_NO_CONTEXT) {
ERROR("Failed to create GLES context");
}

if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context)) {
ERROR("Failed to make GLES context current");
}
}


gbm_bo* CreateGbmBO(gbm_device* gbm, uint64_t width, uint32_t height, uint64_t modifier) {
std::vector<uint64_t> modifiers = { modifier };
gbm_bo* bo = gbm_bo_create_with_modifiers(gbm, width, height,
DRM_FORMAT_ABGR8888, modifiers.data(), 1);
if (!bo) {
ERROR("Failed to create GBM bo");
}
if (gbm_bo_get_modifier(bo) != modifier) {
ERROR("Modifier not accepted when creating GBM bo");
}
return bo;
}

EGLImageKHR CreateEGLImage(gbm_bo* bo) {
uint64_t modifier = gbm_bo_get_modifier(bo);
std::vector<uint32_t> fds = {};
for (int i = 0; i < gbm_bo_get_plane_count(bo); i++) {
fds.push_back(gbm_bo_get_fd_for_plane(bo, i));
}
std::vector<EGLint> egl_image_attrs;
egl_image_attrs.push_back(EGL_WIDTH);
egl_image_attrs.push_back(gbm_bo_get_width(bo));
egl_image_attrs.push_back(EGL_HEIGHT);
egl_image_attrs.push_back(gbm_bo_get_height(bo));
egl_image_attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT);
egl_image_attrs.push_back(gbm_bo_get_format(bo));

egl_image_attrs.push_back(EGL_DMA_BUF_PLANE0_FD_EXT);
egl_image_attrs.push_back(fds[0]);
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT);
egl_image_attrs.push_back(gbm_bo_get_offset(bo, 0));
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT);
egl_image_attrs.push_back(gbm_bo_get_stride_for_plane(bo, 0));
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT);
egl_image_attrs.push_back(modifier & 0xfffffffful);
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT);
egl_image_attrs.push_back(modifier >> 32);

if (gbm_bo_get_plane_count(bo) == 2) {
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE1_FD_EXT);
egl_image_attrs.push_back(fds[1]);
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE1_OFFSET_EXT);
egl_image_attrs.push_back(gbm_bo_get_offset(bo, 1));
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE1_PITCH_EXT);
egl_image_attrs.push_back(gbm_bo_get_stride_for_plane(bo, 1));
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT);
egl_image_attrs.push_back(modifier & 0xfffffffful);
egl_image_attrs.push_back(EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT);
egl_image_attrs.push_back(modifier >> 32);
}

egl_image_attrs.push_back(EGL_NONE);

PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
EGLImageKHR image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
nullptr, egl_image_attrs.data());
if (!image) {
ERROR("Failed to create EGL image");
}

for (int i = 0; i < gbm_bo_get_plane_count(bo); i++) {
close(fds[i]);
}
return image;
}

typedef void *GLeglImageOES;
typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);

GLuint CreateTexture(EGLImageKHR image) {
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
glBindTexture(GL_TEXTURE_2D, 0);
if (glGetError()) {
ERROR("Failed to bind EGL image to texture");
}

return texture;
}

void SetUpFramebuffer(gbm_device* gbm) {
gbm_bo* bo = CreateGbmBO(gbm, kWidth, kHeight, kFramebufferModifier);
EGLImageKHR image = CreateEGLImage(bo);
GLuint texture = CreateTexture(image);
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
if (glGetError()) {
ERROR("Failed to attach texture to fbo");
}
}

GLuint CompileShader(GLenum type, std::string path) {
std::ifstream fstream(path);
if (!fstream) {
ERROR("Unable to read shader: " << path);
}
std::stringstream buffer;
buffer << fstream.rdbuf();
std::string shader_source_tmp = buffer.str();
const char* shader_source = shader_source_tmp.c_str();

GLuint shader = glCreateShader(type);
if (!shader) {
ERROR("Failed to create shader of type: " << type);
}
glShaderSource(shader, 1, &shader_source, nullptr);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (!status) {
GLint log_length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
char shader_log[log_length];
glGetShaderInfoLog(shader, log_length, nullptr, shader_log);
ERROR("Failed to compile shader: " << shader_log);
}
return shader;
}

GLuint CreateProgram() {
GLuint vertex_shader = CompileShader(GL_VERTEX_SHADER, kVertexShaderPath);
GLuint fragment_shader = CompileShader(GL_FRAGMENT_SHADER, kFragmentShaderPath);

GLuint program = glCreateProgram();
if (!program) {
ERROR("Failed to create program");
}
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (!status) {
GLint log_length = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
char program_log[log_length];
glGetProgramInfoLog(program, log_length, nullptr, program_log);
ERROR("Failed to link program: " << program_log);
}
glDetachShader(program, vertex_shader);
glDetachShader(program, fragment_shader);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);

return program;
}

GLuint CreateVBO() {
std::array<Vertex, 6> vertices = {};
// Triangle 1 is upside-down and red.
vertices[0] = { .position = {0.0, -0.5, 0.0}, .color = {1.0, 0.0, 0.0} };
vertices[1] = { .position = {0.5, 0.5, 0.0}, .color = {0.0, 1.0, 0.0} };
vertices[2] = { .position = {-0.5, 0.5, 0.0}, .color = {0.0, 0.0, 1.0} };
// Triangle 1 is upright and green.
vertices[3] = { .position = {0.0, -0.5, 0.0}, .color = {0.0, 1.0, 0.0} };
vertices[4] = { .position = {0.5, 0.5, 0.0}, .color = {0.0, 1.0, 0.0} };
vertices[5] = { .position = {-0.5, 0.5, 0.0}, .color = {0.0, 1.0, 0.0} };

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);
return vbo;
}

GLuint CreateVAO(GLuint vbo, const std::array<uint16_t, 3>& indices) {
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(void*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(void*)offsetof(Vertex, color));
glEnableVertexAttribArray(1);

GLuint ebo;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices.data(), GL_STATIC_DRAW);
return vao;
}

void Draw(gbm_device* gbm, GLuint program, GLuint vao) {
gbm_bo* bo = CreateGbmBO(gbm, kWidth, kHeight, kTextureModifier);
EGLImageKHR image = CreateEGLImage(bo);
GLuint texture = CreateTexture(image);

glViewport(0, 0, kWidth, kHeight);
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glFinish();

glDeleteTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, 0);
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
eglDestroyImageKHR(display, image);
gbm_bo_destroy(bo);
}

int main() {
InitializeEGL();
int drm_fd = open("/dev/dri/renderD128", O_RDWR);
gbm_device* gbm = gbm_create_device(drm_fd);

SetUpFramebuffer(gbm);
GLuint program = CreateProgram();
GLuint vbo = CreateVBO();
GLuint vao = CreateVAO(vbo, { 0, 1, 2 });

while (true) {
Draw(gbm, program, vao);
}

eglMakeCurrent(display, EGL_NO_SURFACE,EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(display, context);
eglTerminate(display);
return EXIT_SUCCESS;
}

+ 12
- 0
dma_import.frag Datei anzeigen

@@ -0,0 +1,12 @@
#version 320 es
precision mediump float;

layout(location = 0) in vec3 fragColor;

layout(location = 0) out vec4 outColor;

uniform sampler2D tex;

void main() {
outColor = vec4(fragColor, 1.0) + texture(tex, vec2(0.5, 0.5));
}

+ 12
- 0
dma_import.vert Datei anzeigen

@@ -0,0 +1,12 @@
#version 320 es
precision mediump float;

layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;

layout(location = 0) out vec3 fragColor;

void main() {
gl_Position = vec4(inPosition, 1.0);
fragColor = inColor;
}

Laden…
Abbrechen
Speichern