UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
dxt_encoder.c File Reference
#include "dxt_encoder.h"
#include "dxt_util.h"
#include "dxt_glsl.h"
#include <GL/glew.h>
#include <string.h>
Include dependency graph for dxt_encoder.c:

Go to the source code of this file.

Classes

struct  dxt_encoder
 

Functions

int dxt_encoder_buffer_allocate (struct dxt_encoder *encoder, unsigned char **image_compressed, int *image_compressed_size)
 
int dxt_encoder_buffer_free (unsigned char *image_compressed)
 
int dxt_encoder_compress (struct dxt_encoder *encoder, DXT_IMAGE_TYPE *image, unsigned char *image_compressed)
 
int dxt_encoder_compress_texture (struct dxt_encoder *encoder, int texture, unsigned char *image_compressed)
 
struct dxt_encoder * dxt_encoder_create (enum dxt_type type, int width, int height, enum dxt_format format, int legacy)
 
int dxt_encoder_destroy (struct dxt_encoder *encoder)
 
static int dxt_prepare_yuv422_shader (struct dxt_encoder *encoder)
 

Variables

const int FORMAT_RGB = 0
 
const int FORMAT_YUV = 1
 
static GLfloat points []
 

Function Documentation

◆ dxt_encoder_buffer_allocate()

int dxt_encoder_buffer_allocate ( struct dxt_encoder * encoder,
unsigned char ** image_compressed,
int * image_compressed_size )

Documented at declaration

Definition at line 444 of file dxt_encoder.c.

445{
446 int size = 0;
447 if ( encoder->type == DXT_TYPE_DXT5_YCOCG )
448 size = (encoder->width / 4) * (encoder->height / 4) * 4 * sizeof(int);
449 else if ( encoder->type == DXT_TYPE_DXT1 )
450 size = (encoder->width / 4) * (encoder->height / 4) * 2 * sizeof(int);
451 else
452 assert(0);
453
454 *image_compressed = (unsigned char*)malloc(size);
455 if ( *image_compressed == NULL )
456 return -1;
457
458 if ( image_compressed_size != NULL )
459 *image_compressed_size = size;
460
461 return 0;
462}
@ DXT_TYPE_DXT1
Definition dxt_common.h:89
@ DXT_TYPE_DXT5_YCOCG
Definition dxt_common.h:91

References DXT_TYPE_DXT1, and DXT_TYPE_DXT5_YCOCG.

Referenced by main(), and perform_encode().

◆ dxt_encoder_buffer_free()

int dxt_encoder_buffer_free ( unsigned char * image_compressed)

Documented at declaration

Definition at line 725 of file dxt_encoder.c.

726{
727 free(image_compressed);
728 return 0;
729}

Referenced by main(), and perform_encode().

◆ dxt_encoder_compress()

int dxt_encoder_compress ( struct dxt_encoder * encoder,
DXT_IMAGE_TYPE * image,
unsigned char * image_compressed )

Documented at declaration

Definition at line 466 of file dxt_encoder.c.

467{
468#ifdef RTDXT_DEBUG
469 glBeginQuery(GL_TIME_ELAPSED_EXT, encoder->queries[0]);
470#endif
471#ifdef RTDXT_DEBUG_HOST
472 TIMER_INIT();
473
474 TIMER_START();
475#endif
476#ifdef HAVE_GPUPERFAPI
477 GPA_BeginPass();
478 GPA_BeginSample(0);
479#endif
480#ifdef USE_PBO_DXT_ENCODER
481 GLubyte *ptr;
482#endif
483
484 int data_size = encoder->width * encoder->height;
485 switch(encoder->format) {
487 data_size *= 2;
488 break;
489 case DXT_FORMAT_RGB:
490 data_size *= 3;
491 break;
492 case DXT_FORMAT_RGBA:
493 case DXT_FORMAT_YUV:
494 data_size *= 4;
495 break;
496 }
497
498 switch(encoder->format) {
500 glBindFramebuffer(GL_FRAMEBUFFER, encoder->fbo444_id);
501 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, encoder->texture_id, 0);
502 glBindTexture(GL_TEXTURE_2D, encoder->texture_yuv422);
503
504 glPushAttrib(GL_VIEWPORT_BIT);
505 glViewport( 0, 0, encoder->width, encoder->height);
506
507#ifdef USE_PBO_DXT_ENCODER
508 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, encoder->pbo_in); // current pbo
509 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width / 2, encoder->height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
510 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, data_size, 0, GL_STREAM_DRAW_ARB);
511 ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
512 if(ptr)
513 {
514 // update data directly on the mapped buffer
515 memcpy(ptr, image, data_size);
516 glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer
517 }
518#else
519 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width / 2, encoder->height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, image);
520#endif
521 glUseProgram(encoder->yuv422_to_444_program);
522#ifdef RTDXT_DEBUG
523 glEndQuery(GL_TIME_ELAPSED_EXT);
524 glBeginQuery(GL_TIME_ELAPSED_EXT, encoder->queries[1]);
525#endif
526#ifdef HAVE_GPUPERFAPI
527 GPA_EndSample();
528 GPA_BeginSample(1);
529#endif
530
531 if(encoder->legacy) {
532 glBegin(GL_QUADS);
533 glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
534 glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
535 glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
536 glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
537 glEnd();
538 } else {
539#if ! defined __APPLE__ || defined __MAC_10_11
540 // Compress
541 glBindVertexArray(encoder->g_vao_422);
542 //glDrawElements(GL_TRIANGLE_STRIP, sizeof(m_quad.indices) / sizeof(m_quad.indices[0]), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
543 glDrawArrays(GL_TRIANGLES, 0, 6);
544 glBindVertexArray(0);
545#endif
546 }
547
548 glPopAttrib();
549 /* there is some problem with restoring viewport state (Mac OS Lion, OpenGL 3.2) */
550 glViewport( 0, 0, (encoder->width + 3) / 4, encoder->height / 4);
551
552 //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
553
554 glUseProgram(encoder->program_compress);
555 glBindFramebuffer(GL_FRAMEBUFFER, encoder->fbo_id);
556 glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
557
558 //gl_check_error();
559 break;
560 case DXT_FORMAT_YUV:
561 case DXT_FORMAT_RGBA:
562 glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
563#ifdef USE_PBO_DXT_ENCODER
564 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, encoder->pbo_in); // current pbo
565 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, 0);
566 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, data_size, 0, GL_STREAM_DRAW_ARB);
567 ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
568 if(ptr)
569 {
570 // update data directly on the mapped buffer
571 memcpy(ptr, image, data_size);
572 glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer
573 }
574#else
575 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, image);
576#endif
577
578 break;
579 case DXT_FORMAT_RGB:
580 glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
581#ifdef USE_PBO_DXT_ENCODER
582 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, encoder->pbo_in); // current pbo
583 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGB, GL_UNSIGNED_BYTE, 0);
584 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, data_size, 0, GL_STREAM_DRAW_ARB);
585 ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
586 if(ptr)
587 {
588 // update data directly on the mapped buffer
589 memcpy(ptr, image, data_size);
590 glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer
591 }
592#else
593 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGB, GL_UNSIGNED_BYTE, image);
594#endif
595 break;
596 }
597#ifdef RTDXT_DEBUG
598 glEndQuery(GL_TIME_ELAPSED_EXT);
599 glBeginQuery(GL_TIME_ELAPSED_EXT, encoder->queries[2]);
600#endif
601#ifdef RTDXT_DEBUG_HOST
602 glFinish();
603 TIMER_STOP_PRINT("Tex Load (+->444): ");
604 TIMER_START();
605#endif
606
607#ifdef HAVE_GPUPERFAPI
608 GPA_EndSample();
609 GPA_BeginSample(2);
610#endif
611
612 return dxt_encoder_compress_texture(encoder, encoder->texture_id, image_compressed);
613}
#define DXT_IMAGE_GL_TYPE
Definition dxt_common.h:72
#define TIMER_STOP_PRINT(text)
Definition dxt_common.h:64
@ DXT_FORMAT_RGBA
Definition dxt_common.h:80
@ DXT_FORMAT_YUV
Definition dxt_common.h:81
@ DXT_FORMAT_YUV422
Definition dxt_common.h:82
@ DXT_FORMAT_RGB
Definition dxt_common.h:79
#define TIMER_START()
Definition dxt_common.h:56
#define TIMER_INIT()
Definition dxt_common.h:52
int dxt_encoder_compress_texture(struct dxt_encoder *encoder, int texture, unsigned char *image_compressed)

References dxt_encoder_compress_texture(), DXT_FORMAT_RGB, DXT_FORMAT_RGBA, DXT_FORMAT_YUV, DXT_FORMAT_YUV422, DXT_IMAGE_GL_TYPE, TIMER_INIT, TIMER_START, and TIMER_STOP_PRINT.

Referenced by main(), and perform_encode().

Here is the call graph for this function:

◆ dxt_encoder_compress_texture()

int dxt_encoder_compress_texture ( struct dxt_encoder * encoder,
int texture,
unsigned char * image_compressed )

Compress image by DXT encoder

Parameters
encoderEncoder structure
textexture index
image_compressedPointer to buffer where compressed image data will be placed
Returns
0 if succeeds, otherwise nonzero

Definition at line 617 of file dxt_encoder.c.

618{
619#ifdef USE_PBO_DXT_ENCODER
620 GLubyte *ptr;
621#endif
622
623 glBindTexture(GL_TEXTURE_2D, texture);
624
625 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
626 assert(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER));
627
628 glClearColor(1,0,0,1);
629 glClear(GL_COLOR_BUFFER_BIT);
630
631 if(encoder->legacy) {
632 glBegin(GL_QUADS);
633 glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
634 glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
635 glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
636 glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
637 glEnd();
638 } else {
639#if ! defined __APPLE__ || defined __MAC_10_11
640 // Compress
641 glBindVertexArray(encoder->g_vao);
642 //glDrawElements(GL_TRIANGLE_STRIP, sizeof(m_quad.indices) / sizeof(m_quad.indices[0]), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
643 glDrawArrays(GL_TRIANGLES, 0, 6);
644 glBindVertexArray(0);
645#endif
646 }
647#ifdef HAVE_GPUPERFAPI
648 GPA_EndSample();
649 GPA_BeginSample(3);
650#endif
651#ifdef RTDXT_DEBUG
652 glEndQuery(GL_TIME_ELAPSED_EXT);
653 glBeginQuery(GL_TIME_ELAPSED_EXT, encoder->queries[3]);
654#endif
655#ifdef RTDXT_DEBUG_HOST
656 glFinish();
657 TIMER_STOP_PRINT("Texture Compress: ");
658 TIMER_START();
659#endif
660
661
662 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
663
664#ifdef USE_PBO_DXT_ENCODER
665 // Read back
666 // read pixels from framebuffer to PBO
667 // glReadPixels() should return immediately.
668 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, encoder->pbo_out);
669 if ( encoder->type == DXT_TYPE_DXT5_YCOCG )
670 glReadPixels(0, 0, (encoder->width + 3) / 4, (encoder->height + 3) / 4, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, 0);
671 else
672 glReadPixels(0, 0, (encoder->width + 3) / 4, (encoder->height + 3) / 4 , GL_RGBA_INTEGER_EXT, GL_UNSIGNED_SHORT, 0);
673
674 // map the PBO to process its data by CPU
675 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, encoder->pbo_out);
676 ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
677 GL_READ_ONLY_ARB);
678 if(ptr)
679 {
680 memcpy(image_compressed, ptr, ((encoder->width + 3) / 4 * 4) * ((encoder->height + 3) / 4 * 4) / (encoder->type == DXT_TYPE_DXT5_YCOCG ? 1 : 2));
681 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
682 }
683
684 // back to conventional pixel operation
685 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
686#else
687 glReadPixels(0, 0, (encoder->width + 3) / 4, (encoder->height + 3) / 4, GL_RGBA_INTEGER_EXT,
688 encoder->type == DXT_TYPE_DXT5_YCOCG ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, image_compressed);
689#endif
690
691
692#ifdef RTDXT_DEBUG_HOST
693 glFinish();
694 TIMER_STOP_PRINT("Texture Save: ");
695#endif
696#ifdef RTDXT_DEBUG
697 glEndQuery(GL_TIME_ELAPSED_EXT);
698 {
699 GLint available = 0;
700 GLuint64 load = 0,
701 convert = 0,
702 compress = 0,
703 store = 0;
704 while (!available) {
705 glGetQueryObjectiv(encoder->queries[3], GL_QUERY_RESULT_AVAILABLE, &available);
706 }
707 glGetQueryObjectui64vEXT(encoder->queries[0], GL_QUERY_RESULT, &load);
708 glGetQueryObjectui64vEXT(encoder->queries[1], GL_QUERY_RESULT, &convert);
709 glGetQueryObjectui64vEXT(encoder->queries[2], GL_QUERY_RESULT, &compress);
710 glGetQueryObjectui64vEXT(encoder->queries[3], GL_QUERY_RESULT, &store);
711 printf("Load: %8lu; YUV444->YUV422: %8lu; compress: %8lu; store: %8lu\n",
712 load, convert, compress, store);
713 }
714#endif
715#ifdef HAVE_GPUPERFAPI
716 GPA_EndSample();
717 GPA_EndPass();
718#endif
719
720 return 0;
721}
convert_t convert

References convert, DXT_TYPE_DXT5_YCOCG, TIMER_START, and TIMER_STOP_PRINT.

Referenced by dxt_encoder_compress().

◆ dxt_encoder_create()

struct dxt_encoder * dxt_encoder_create ( enum dxt_type type,
int width,
int height,
enum dxt_format format,
int legacy )

Documented at declaration

Todo
What about generated textures etc. ?

Definition at line 230 of file dxt_encoder.c.

231{
232 struct dxt_encoder* encoder = (struct dxt_encoder*)malloc(sizeof(struct dxt_encoder));
233
234#ifndef HAVE_MACOSX
235 glewExperimental = GL_TRUE;
236 GLenum err = glewInit();
237 assert(err == GLEW_OK);
238#endif
239
240 if ( encoder == NULL )
241 return NULL;
242 encoder->type = type;
243 encoder->width = width;
244 encoder->height = height;
245 encoder->format = format;
246 encoder->legacy = legacy;
247
248 if(legacy) {
249 glEnable(GL_TEXTURE_2D);
250 }
251
252 //glEnable(GL_TEXTURE_2D);
253#ifdef HAVE_GPUPERFAPI
254 GPA_EnableAllCounters();
255#endif
256
257 glGenFramebuffers(1, &encoder->fbo_id);
258 glBindFramebuffer(GL_FRAMEBUFFER, encoder->fbo_id);
259
260#ifdef USE_PBO_DXT_ENCODER
261 int bpp;
262 if(format == DXT_FORMAT_RGB) {
263 bpp = 3;
264 } else {
265 bpp = 4;
266 }
267
268 glGenBuffersARB(1, &encoder->pbo_in); //Allocate PBO
269 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, encoder->pbo_in);
270 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,width*height*bpp,0,GL_STREAM_DRAW_ARB);
271 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
272
273 glGenBuffersARB(1, &encoder->pbo_out); //Allocate PBO
274 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, encoder->pbo_out);
275 glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, ((width + 3) / 4 * 4) * ((height + 3) / 4 * 4) / (encoder->type == DXT_TYPE_DXT5_YCOCG ? 1 : 2), 0, GL_STREAM_READ_ARB);
276 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
277
278#endif
279
280 GLuint fbo_tex;
281 glGenTextures(1, &fbo_tex);
282 glBindTexture(GL_TEXTURE_2D, fbo_tex);
283 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
284 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
285 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
287 if ( encoder->type == DXT_TYPE_DXT5_YCOCG )
288 glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA32UI_EXT, (encoder->width + 3) / 4 * 4, (encoder->height + 3) / 4, 0, GL_RGBA_INTEGER_EXT, GL_INT, 0);
289 else
290 glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA16UI_EXT, (encoder->width + 3) / 4 * 4, (encoder->height + 3) / 4, 0, GL_RGBA_INTEGER_EXT, GL_INT, 0);
291 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_tex, 0);
292 glBindFramebuffer(GL_FRAMEBUFFER, 0);
293
294 // Create program [display] and its shader
295 encoder->program_compress = glCreateProgram();
296 // Create fragment shader from file
297 encoder->shader_fragment_compress = 0;
298 if ( encoder->type == DXT_TYPE_DXT5_YCOCG ) {
299 if(encoder->legacy) {
301 encoder->shader_fragment_compress = dxt_shader_create_from_source(fp_compress_dxt5ycocg_yuv_legacy, GL_FRAGMENT_SHADER);
302 } else {
303 encoder->shader_fragment_compress = dxt_shader_create_from_source(fp_compress_dxt5ycocg_legacy, GL_FRAGMENT_SHADER);
304 }
305 } else {
307 encoder->shader_fragment_compress = dxt_shader_create_from_source(fp_compress_dxt5ycocg_yuv, GL_FRAGMENT_SHADER);
308 } else {
309 encoder->shader_fragment_compress = dxt_shader_create_from_source(fp_compress_dxt5ycocg, GL_FRAGMENT_SHADER);
310 }
311 }
312 } else {
314 encoder->shader_fragment_compress = dxt_shader_create_from_source(encoder->legacy ? fp_compress_dxt1_yuv_legacy : fp_compress_dxt1_yuv, GL_FRAGMENT_SHADER);
315 } else if (((format == DXT_FORMAT_YUV422 || format == DXT_FORMAT_YUV) && encoder->type == DXT_TYPE_DXT1_YUV) ||
317 encoder->shader_fragment_compress = dxt_shader_create_from_source(encoder->legacy ? fp_compress_dxt1_legacy : fp_compress_dxt1, GL_FRAGMENT_SHADER);
318 } else {
319 fprintf(stderr, "RGB(A) to DXT1_YUV is not supported!\n");
320 }
321 }
322 if ( encoder->shader_fragment_compress == 0 ) {
323 fprintf(stderr, "Failed to compile fragment compress program!\n");
324 free(encoder);
325 return NULL;
326 }
327 // Create vertex shader from file
328 encoder->shader_vertex_compress = 0;
329 if(encoder->legacy) {
330 encoder->shader_vertex_compress = dxt_shader_create_from_source(vp_compress_legacy, GL_VERTEX_SHADER);
331 } else {
332 encoder->shader_vertex_compress = dxt_shader_create_from_source(vp_compress, GL_VERTEX_SHADER);
333 }
334 if ( encoder->shader_vertex_compress == 0 ) {
335 fprintf(stderr, "Failed to compile vertex compress program!\n");
336 free(encoder);
337 return NULL;
338 }
339 // Attach shader to program and link the program
340 glAttachShader(encoder->program_compress, encoder->shader_fragment_compress);
341 glAttachShader(encoder->program_compress, encoder->shader_vertex_compress);
342 glLinkProgram(encoder->program_compress);
343
344 char log[32768];
345 glGetProgramInfoLog(encoder->program_compress, 32768, NULL, (GLchar*)log);
346 if ( strlen(log) > 0 )
347 printf("Link Log: %s\n", log);
348
349
350 glGenTextures(1, &encoder->texture_id);
351 glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
356 if(format == DXT_FORMAT_RGB) {
357 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, encoder->width, encoder->height, 0, GL_RGB, GL_BYTE, NULL);
358 } else {
359 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, encoder->width, encoder->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
360 }
361
362 //glActiveTexture(GL_TEXTURE0);
363
367 free(encoder);
368 return NULL;
369 }
370 }
371
372 glBindTexture(GL_TEXTURE_2D, encoder->texture_id);
373 //glClear(GL_COLOR_BUFFER_BIT);
374
375 glViewport(0, 0, (encoder->width + 3) / 4, encoder->height / 4);
376 glDisable(GL_DEPTH_TEST);
377
378 // User compress program and set image size parameters
379 glUseProgram(encoder->program_compress);
380//glBindFragDataLocation(encoder->program_compress, 0, "colorInt");
381 glUniform1i(glGetUniformLocation(encoder->program_compress, "image"), 0);
382
384 glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), FORMAT_YUV);
385 } else {
386 glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), FORMAT_RGB);
387 }
388 glUniform2f(glGetUniformLocation(encoder->program_compress, "imageSize"), encoder->width, (encoder->height + 3) / 4 * 4);
389 glUniform1f(glGetUniformLocation(encoder->program_compress, "textureWidth"), (encoder->width + 3) / 4 * 4);
390
391 if(!encoder->legacy) {
392#if ! defined __APPLE__ || defined __MAC_10_11
393 GLint g_vertexLocation;
394
395 // ToDo:
396 glGenVertexArrays(1, &encoder->g_vao);
397
398 // ToDo:
399 glBindVertexArray(encoder->g_vao);
400
401 // http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml
402 g_vertexLocation = glGetAttribLocation(encoder->program_compress, "position");
403
404 // http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml
405 glGenBuffers(1, &encoder->g_vertices);
406
407 // http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml
408 glBindBuffer(GL_ARRAY_BUFFER, encoder->g_vertices);
409
410 // http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml
411 //glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);
412 glBufferData(GL_ARRAY_BUFFER, 8 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);
413
414 // http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml
415 //glUseProgram(g_program.program);
416
417 // http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml
418 glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
419
420 // http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml
421 glEnableVertexAttribArray(g_vertexLocation);
422
423 glBindFragDataLocation(encoder->program_compress, 0, "colorOut");
424#endif
425 }
426
427 // Render to framebuffer
428 glBindFramebuffer(GL_FRAMEBUFFER, encoder->fbo_id);
429
430#ifdef HAVE_GPUPERFAPI
431 GPA_BeginSession( &encoder->sessionID );
432 GPA_GetPassCount( &encoder->numRequiredPasses );
433 encoder->currentWaitSessionID = 0;
434#endif
435#ifdef RTDXT_DEBUG
436 glGenQueries(4, encoder->queries);
437#endif
438
439 return encoder;
440}
@ DXT_TYPE_DXT1_YUV
Definition dxt_common.h:90
static GLfloat points[]
Definition dxt_encoder.c:61
const int FORMAT_YUV
Definition dxt_encoder.c:71
const int FORMAT_RGB
Definition dxt_encoder.c:70
static int dxt_prepare_yuv422_shader(struct dxt_encoder *encoder)
GLuint dxt_shader_create_from_source(const char *source, GLenum type)
Definition dxt_util.c:32
Option::OptType type
Definition settings.cpp:194
enum dxt_format format
Definition dxt_encoder.c:88
unsigned int legacy
Definition dxt_encoder.c:76

References DXT_FORMAT_RGB, DXT_FORMAT_RGBA, DXT_FORMAT_YUV, DXT_FORMAT_YUV422, dxt_prepare_yuv422_shader(), dxt_shader_create_from_source(), DXT_TYPE_DXT1, DXT_TYPE_DXT1_YUV, DXT_TYPE_DXT5_YCOCG, dxt_encoder::format, FORMAT_RGB, FORMAT_YUV, dxt_encoder::height, dxt_encoder::legacy, points, type, and dxt_encoder::width.

Referenced by main(), and perform_encode().

Here is the call graph for this function:

◆ dxt_encoder_destroy()

int dxt_encoder_destroy ( struct dxt_encoder * encoder)

Documented at declaration

Definition at line 733 of file dxt_encoder.c.

734{
735#ifdef HAVE_GPUPERFAPI
736 GPA_EndSession();
737 bool readyResult = FALSE;
738 if ( encoder->sessionID != encoder->currentWaitSessionID )
739 {
740 GPA_Status sessionStatus;
741 sessionStatus = GPA_IsSessionReady( &readyResult,
742 encoder->currentWaitSessionID );
743 while ( sessionStatus == GPA_STATUS_ERROR_SESSION_NOT_FOUND )
744 {
745 // skipping a session which got overwritten
746 encoder->currentWaitSessionID++;
747 sessionStatus = GPA_IsSessionReady( &readyResult,
748 encoder->currentWaitSessionID );
749 }
750 }
751 if ( readyResult )
752 {
753 WriteSession( encoder->currentWaitSessionID,
754 "GPUPerfAPI-RTDXT-Results.csv" );
755 encoder->currentWaitSessionID++;
756 }
757
758#endif
759 glDeleteShader(encoder->shader_fragment_compress);
760 glDeleteShader(encoder->shader_vertex_compress);
761 glDeleteProgram(encoder->program_compress);
762 free(encoder);
763 return 0;
764}
#define FALSE

References FALSE.

Referenced by main(), and perform_encode().

◆ dxt_prepare_yuv422_shader()

static int dxt_prepare_yuv422_shader ( struct dxt_encoder * encoder)
static

Definition at line 140 of file dxt_encoder.c.

140 {
141 encoder->yuv422_to_444_fp = 0;
142 if(encoder->legacy) {
143 encoder->yuv422_to_444_fp = dxt_shader_create_from_source(fp_yuv422_to_yuv_444_legacy, GL_FRAGMENT_SHADER);
144 } else {
145 encoder->yuv422_to_444_fp = dxt_shader_create_from_source(fp_yuv422_to_yuv_444, GL_FRAGMENT_SHADER);
146 }
147
148 if ( encoder->yuv422_to_444_fp == 0) {
149 fprintf(stderr, "Failed to compile YUV422->YUV444 fragment program!\n");
150 return 0;
151 }
152
153 if(encoder->legacy) {
154 encoder->yuv422_to_444_vp = dxt_shader_create_from_source(vp_compress_legacy, GL_VERTEX_SHADER);
155 } else {
156 encoder->yuv422_to_444_vp = dxt_shader_create_from_source(vp_compress, GL_VERTEX_SHADER);
157 }
158
159 encoder->yuv422_to_444_program = glCreateProgram();
160 glAttachShader(encoder->yuv422_to_444_program, encoder->yuv422_to_444_fp);
161 glAttachShader(encoder->yuv422_to_444_program, encoder->yuv422_to_444_vp);
162 glLinkProgram(encoder->yuv422_to_444_program);
163
164 if(!encoder->legacy) {
165#if ! defined __APPLE__ || defined __MAC_10_11
166 GLint g_vertexLocation;
167 GLuint g_vertices;
168
169 // ToDo:
170 glGenVertexArrays(1, &encoder->g_vao_422);
171
172 // ToDo:
173 glBindVertexArray(encoder->g_vao_422);
174
175 // http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml
176 g_vertexLocation = glGetAttribLocation(encoder->yuv422_to_444_program, "position");
177
178 // http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml
179 glGenBuffers(1, &g_vertices);
180
181 // http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml
182 glBindBuffer(GL_ARRAY_BUFFER, g_vertices);
183
184 // http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml
185 //glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);
186 glBufferData(GL_ARRAY_BUFFER, 8 * 4 * sizeof(GLfloat), (GLfloat*) points, GL_STATIC_DRAW);
187
188 // http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml
189 glUseProgram(encoder->yuv422_to_444_program);
190
191 // http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml
192 glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
193
194 // http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml
195 glEnableVertexAttribArray(g_vertexLocation);
196
197 glBindFragDataLocation(encoder->yuv422_to_444_program, 0, "colorOut");
198
199 glUseProgram(0);
200#endif
201 }
202
203 char log[32768];
204 glGetProgramInfoLog(encoder->yuv422_to_444_program, 32768, NULL, (GLchar*)log);
205 if ( strlen(log) > 0 )
206 printf("Link Log: %s\n", log);
207
208 glGenTextures(1, &encoder->texture_yuv422);
209 glBindTexture(GL_TEXTURE_2D, encoder->texture_yuv422);
210 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
211 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
214 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, encoder->width / 2, encoder->height,
215 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
216
217 glUseProgram(encoder->yuv422_to_444_program);
218 glUniform1i(glGetUniformLocation(encoder->yuv422_to_444_program, "image"), 0);
219 glUniform1f(glGetUniformLocation(encoder->yuv422_to_444_program, "imageWidth"),
220 (GLfloat) encoder->width);
221
222 // Create fbo
223 glGenFramebuffers(1, &encoder->fbo444_id);
224 return 1;
225}

References dxt_shader_create_from_source(), and points.

Referenced by dxt_encoder_create().

Here is the call graph for this function:

Variable Documentation

◆ FORMAT_RGB

const int FORMAT_RGB = 0

Definition at line 70 of file dxt_encoder.c.

Referenced by dxt_encoder_create().

◆ FORMAT_YUV

const int FORMAT_YUV = 1

Definition at line 71 of file dxt_encoder.c.

Referenced by dxt_encoder_create().

◆ points

GLfloat points[]
static
Initial value:
= { -1.0f, -1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f
}

Copyright (c) 2011, Martin Srom All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition at line 61 of file dxt_encoder.c.

61 { -1.0f, -1.0f, 0.0f, 1.0f,
62 1.0f, -1.0f, 0.0f, 1.0f,
63 -1.0f, 1.0f, 0.0f, 1.0f,
64 /* second triangle */
65 1.0f, -1.0f, 0.0f, 1.0f,
66 -1.0f, 1.0f, 0.0f, 1.0f,
67 1.0f, 1.0f, 0.0f, 1.0f
68};

Referenced by dxt_encoder_create(), and dxt_prepare_yuv422_shader().