forked from CESNET/UltraGrid
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrgb2dxt6.c
More file actions
136 lines (113 loc) · 3.7 KB
/
Copy pathrgb2dxt6.c
File metadata and controls
136 lines (113 loc) · 3.7 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdio.h>
#include <stdlib.h>
#include "cuda_dxt.h"
static void usage(const char * const name, const char * const message) {
printf("ERROR: %s\n", message);
printf("Usage: %s width height input.rgb output.yog\n", name);
}
int main(int argc, char** argv) {
FILE *in_file, *out_file;
size_t in_size, out_size;
int size_x, size_y;
void *in_host = 0, *out_host = 0, *out_gpu = 0, *in_gpu = 0;
unsigned int * header;
cudaEvent_t event_begin, event_end;
float kernel_time_ms;
/* check arguments */
if(5 != argc) {
usage(argv[0], "Incorrect argument count.");
return -1;
}
/* get image size */
size_x = atoi(argv[1]);
size_y = atoi(argv[2]);
if(size_x <= 0 || (size_x & 3) || size_y == 0 || (abs(size_y) & 3)) {
usage(argv[0], "Image sizes must be positive numbers divisible by 4.");
return -1;
}
/* Check CUDA device */
if(cudaSuccess != cudaSetDevice(0)) {
usage(argv[0], "Cannot set CUDA device #0.");
return -1;
}
/* allocate buffers (both GPU and host buffers) */
out_size = size_x * abs(size_y);
in_size = out_size * 3;
cudaMallocHost(&in_host, in_size);
cudaMallocHost(&out_host, out_size);
cudaMalloc(&in_gpu, in_size);
cudaMalloc(&out_gpu, out_size);
if(!in_host || !out_host || !out_gpu || !in_gpu) {
usage(argv[0], "Cannot allocate buffers.\n");
return -1;
}
/* open input file */
in_file = fopen(argv[3], "r");
if(!in_file) {
usage(argv[0], "Could not open input file.");
return -1;
}
#if 0
/* check file size */
fseek(in_file, 0, SEEK_END);
if(ftell(in_file) != (long int)in_size) {
usage(argv[0], "Input file size does not match.");
return -1;
}
fseek(in_file, 0, SEEK_SET);
#endif
/* load data */
if(1 != fread(in_host, in_size, 1, in_file)) {
usage(argv[0], "Could not read from input file.");
return -1;
}
fclose(in_file);
/* copy data into GPU buffer */
if(cudaSuccess != cudaMemcpy(in_gpu, in_host, in_size, cudaMemcpyHostToDevice)) {
usage(argv[0], "Could not copy input to GPU.");
return -1;
}
/* prepare events for time emasurement and begin */
cudaEventCreate(&event_end);
cudaEventCreate(&event_begin);
cudaEventRecord(event_begin, 0);
/* compress */
if(cuda_rgb_to_dxt6(in_gpu, out_gpu, size_x, size_y, 0)) {
usage(argv[0], "DXT Encoder error.");
return -1;
}
/* measure kernel time */
cudaEventRecord(event_end, 0);
/* check kernel call */
if(cudaSuccess != cudaDeviceSynchronize()) {
usage(argv[0], cudaGetErrorString(cudaGetLastError()));
return -1;
}
/* print the time */
cudaEventElapsedTime(&kernel_time_ms, event_begin, event_end);
printf("DXT6 compression time: %.3f ms.\n", kernel_time_ms);
/* copy back to host memory */
if(cudaSuccess != cudaMemcpy((char*)out_host, out_gpu, out_size, cudaMemcpyDeviceToHost)) {
usage(argv[0], "Could not copy output to host memory.");
return -1;
}
/* open output file */
out_file = fopen(argv[4], "w");
if(!out_file) {
usage(argv[0], "Could not open output file for writing.");
return -1;
}
/* write output into the file */
if(1 != fwrite(out_host, out_size, 1, out_file)) {
usage(argv[0], "Could not write into output file.");
return -1;
}
fclose(out_file);
/* free buffers */
cudaFreeHost(in_host);
cudaFreeHost(out_host);
cudaFree(in_gpu);
cudaFree(out_gpu);
/* indicate success */
return 0;
}