123
123
static void glDrawTex(GL *gl, GLfloat x, GLfloat y, GLfloat w, GLfloat h,
124
124
GLfloat tx, GLfloat ty, GLfloat tw, GLfloat th,
125
125
int sx, int sy, int rect_tex, int is_yv12, int flip);
126
static int loadGPUProgram(GL *gl, GLenum target, char *prog);
126
static int loadGPUProgram(struct vo *vo, GL *gl, GLenum target, char *prog);
127
127
//! do not use YUV conversion, this should always stay 0
128
128
#define YUV_CONVERSION_NONE 0
129
129
//! use nVidia specific register combiners for YUV conversion
193
193
} gl_conversion_params_t;
195
195
static int glAutodetectYUVConversion(GL *gl);
196
static void glSetupYUVConversion(GL *gl, gl_conversion_params_t *params);
196
static void glSetupYUVConversion(struct vo *vo, GL *gl,
197
gl_conversion_params_t *params);
197
198
static void glEnableYUVConversion(GL *gl, GLenum target, int type);
198
199
static void glDisableYUVConversion(GL *gl, GLenum target, int type);
428
429
* \param text if set use the GL_ATI_text_fragment_shader API as
431
static void glSetupYUVFragmentATI(GL *gl, struct mp_csp_params *csp_params,
432
static void glSetupYUVFragmentATI(struct vo *vo, GL *gl,
433
struct mp_csp_params *csp_params, int text)
435
436
float yuv2rgb[3][4];
437
438
gl->GetIntegerv(GL_MAX_TEXTURE_UNITS, &i);
439
mp_msg(MSGT_VO, MSGL_ERR,
440
"[gl] 3 texture units needed for YUV combiner (ATI) support (found %i)\n", i);
440
MP_ERR(vo, "3 texture units needed for YUV combiner (ATI) support (found %i)\n", i);
442
442
mp_get_yuv2rgb_coeffs(csp_params, yuv2rgb);
443
443
for (i = 0; i < 3; i++) {
460
460
if (!gl->BeginFragmentShader || !gl->EndFragmentShader ||
461
461
!gl->SetFragmentShaderConstant || !gl->SampleMap ||
462
462
!gl->ColorFragmentOp2 || !gl->ColorFragmentOp3) {
463
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Combiner (ATI) functions missing!\n");
463
MP_ERR(vo, "Combiner (ATI) functions missing!\n");
466
466
gl->GetIntegerv(GL_NUM_FRAGMENT_REGISTERS_ATI, &i);
468
mp_msg(MSGT_VO, MSGL_ERR,
469
"[gl] 3 registers needed for YUV combiner (ATI) support (found %i)\n", i);
468
MP_ERR(vo, "3 registers needed for YUV combiner (ATI) support (found %i)\n", i);
470
469
gl->BeginFragmentShader();
471
470
gl->SetFragmentShaderConstant(GL_CON_0_ATI, c0);
472
471
gl->SetFragmentShaderConstant(GL_CON_1_ATI, c1);
514
513
yuv2rgb[0][1], yuv2rgb[1][1], yuv2rgb[2][1],
515
514
yuv2rgb[0][2], yuv2rgb[1][2], yuv2rgb[2][2],
516
515
yuv2rgb[0][3], yuv2rgb[1][3], yuv2rgb[2][3]);
517
mp_msg(MSGT_VO, MSGL_DBG2, "[gl] generated fragment program:\n%s\n",
519
loadGPUProgram(gl, GL_TEXT_FRAGMENT_SHADER_ATI, buffer);
516
MP_DBG(vo, "generated fragment program:\n%s\n", buffer);
517
loadGPUProgram(vo, gl, GL_TEXT_FRAGMENT_SHADER_ATI, buffer);
833
831
* \param texu contains next free texture unit number
834
832
* \param texs texture unit ids for the scaler are stored in this array
836
static void create_scaler_textures(GL *gl, int scaler, int *texu, char *texs)
834
static void create_scaler_textures(struct vo *vo, GL *gl, int scaler, int *texu,
838
837
switch (scaler) {
839
838
case YUV_SCALER_BILIN:
862
861
* \param texu contains next free texture unit number
863
862
* \param texs texture unit ids for the conversion are stored in this array
865
static void create_conv_textures(GL *gl, gl_conversion_params_t *params,
864
static void create_conv_textures(struct vo *vo, GL *gl,
865
gl_conversion_params_t *params,
866
866
int *texu, char *texs)
868
868
unsigned char *lookup_data = NULL;
1015
1015
* \param prog program string
1016
1016
* \return 1 on success, 0 otherwise
1018
static int loadGPUProgram(GL *gl, GLenum target, char *prog)
1018
static int loadGPUProgram(struct vo *vo, GL *gl, GLenum target, char *prog)
1021
1021
GLint cur = 0, max = 0, err = 0;
1022
1022
if (!gl->ProgramString) {
1023
mp_msg(MSGT_VO, MSGL_ERR, "[gl] Missing GPU program function\n");
1023
MP_ERR(vo, "Missing GPU program function\n");
1026
1026
gl->ProgramString(target, GL_PROGRAM_FORMAT_ASCII, strlen(prog), prog);
1027
1027
gl->GetIntegerv(GL_PROGRAM_ERROR_POSITION, &err);
1028
1028
if (err != -1) {
1029
mp_msg(MSGT_VO, MSGL_ERR,
1030
"[gl] Error compiling fragment program, make sure your card supports\n"
1031
"[gl] GL_ARB_fragment_program (use glxinfo to check).\n"
1032
"[gl] Error message:\n %s at %.10s\n",
1030
"Error compiling fragment program, make sure your card supports\n"
1031
" GL_ARB_fragment_program (use glxinfo to check).\n"
1032
" Error message:\n %s at %.10s\n",
1033
1033
gl->GetString(GL_PROGRAM_ERROR_STRING), &prog[err]);
1036
1036
if (!gl->GetProgramivARB || !mp_msg_test(MSGT_VO, MSGL_DBG2))
1038
mp_msg(MSGT_VO, MSGL_V, "[gl] Program statistics:\n");
1038
MP_VERBOSE(vo, "Program statistics:\n");
1039
1039
for (i = 0; progstats[i].name; i++) {
1040
1040
gl->GetProgramivARB(target, progstats[i].cur, &cur);
1041
1041
gl->GetProgramivARB(target, progstats[i].max, &max);
1042
mp_msg(MSGT_VO, MSGL_V, "[gl] %s: %i/%i\n", progstats[i].name, cur,
1042
MP_VERBOSE(vo, " %s: %i/%i\n", progstats[i].name, cur, max);
1052
1051
* \param parms struct containing parameters like conversion and scaler type,
1053
1052
* brightness, ...
1055
static void glSetupYUVFragprog(GL *gl, gl_conversion_params_t *params)
1054
static void glSetupYUVFragprog(struct vo *vo, GL *gl,
1055
gl_conversion_params_t *params)
1057
1057
int type = params->type;
1058
1058
int texw = params->texw;
1076
1076
// for red, green, blue and the constant offsets
1077
1077
float yuv2rgb[3][4];
1078
1078
int noise = params->noise_strength != 0;
1079
create_conv_textures(gl, params, &cur_texu, conv_texs);
1080
create_scaler_textures(gl, YUV_LUM_SCALER(type), &cur_texu, lum_scale_texs);
1079
create_conv_textures(vo, gl, params, &cur_texu, conv_texs);
1080
create_scaler_textures(vo, gl, YUV_LUM_SCALER(type), &cur_texu, lum_scale_texs);
1081
1081
if (YUV_CHROM_SCALER(type) == YUV_LUM_SCALER(type))
1082
1082
memcpy(chrom_scale_texs, lum_scale_texs, sizeof(chrom_scale_texs));
1084
create_scaler_textures(gl, YUV_CHROM_SCALER(type), &cur_texu,
1084
create_scaler_textures(vo, gl, YUV_CHROM_SCALER(type), &cur_texu,
1085
1085
chrom_scale_texs);
1092
1092
gl->GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &i);
1093
1093
if (i < cur_texu)
1094
mp_msg(MSGT_VO, MSGL_ERR,
1095
"[gl] %i texture units needed for this type of YUV fragment support (found %i)\n",
1094
MP_ERR(vo, "%i texture units needed for this type of YUV fragment support (found %i)\n",
1097
1096
if (!gl->ProgramString) {
1098
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] ProgramString function missing!\n");
1097
MP_FATAL(vo, "ProgramString function missing!\n");
1101
1100
append_template(prog, prog_hdr);
1122
1121
append_template(prog, yuv_lookup3d_prog_template);
1125
mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n",
1126
YUV_CONVERSION(type));
1124
MP_ERR(vo, "unknown conversion type %i\n", YUV_CONVERSION(type));
1129
1127
for (int r = 0; r < 3; r++) {
1157
1155
append_template(prog, "MOV result.color.rgb, res;\nEND");
1159
mp_msg(MSGT_VO, MSGL_DBG2, "[gl] generated fragment program:\n%s\n",
1161
loadGPUProgram(gl, GL_FRAGMENT_PROGRAM, yuv_prog);
1157
MP_DBG(vo, "generated fragment program:\n%s\n", yuv_prog);
1158
loadGPUProgram(vo, gl, GL_FRAGMENT_PROGRAM, yuv_prog);
1162
1159
talloc_free(yuv_prog);
1185
1182
* brightness, ...
1186
1183
* \ingroup glconversion
1188
static void glSetupYUVConversion(GL *gl, gl_conversion_params_t *params)
1185
static void glSetupYUVConversion(struct vo *vo, GL *gl,
1186
gl_conversion_params_t *params)
1190
1188
if (params->chrom_texw == 0)
1191
1189
params->chrom_texw = 1;
1193
1191
params->chrom_texh = 1;
1194
1192
switch (YUV_CONVERSION(params->type)) {
1195
1193
case YUV_CONVERSION_COMBINERS_ATI:
1196
glSetupYUVFragmentATI(gl, ¶ms->csp_params, 0);
1194
glSetupYUVFragmentATI(vo, gl, ¶ms->csp_params, 0);
1198
1196
case YUV_CONVERSION_TEXT_FRAGMENT:
1199
glSetupYUVFragmentATI(gl, ¶ms->csp_params, 1);
1197
glSetupYUVFragmentATI(vo, gl, ¶ms->csp_params, 1);
1201
1199
case YUV_CONVERSION_FRAGMENT_LOOKUP:
1202
1200
case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
1203
1201
case YUV_CONVERSION_FRAGMENT:
1204
1202
case YUV_CONVERSION_FRAGMENT_POW:
1205
glSetupYUVFragprog(gl, params);
1203
glSetupYUVFragprog(vo, gl, params);
1207
1205
case YUV_CONVERSION_NONE:
1210
mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n",
1211
YUV_CONVERSION(params->type));
1208
MP_ERR(vo, "unknown conversion type %i\n", YUV_CONVERSION(params->type));
1358
1355
struct gl_priv *p = vo->priv;
1359
1356
GL *gl = p->gl;
1361
mp_msg(MSGT_VO, MSGL_V, "[gl] Resize: %dx%d\n", x, y);
1358
MP_VERBOSE(vo, "Resize: %dx%d\n", x, y);
1362
1359
gl->Viewport(0, 0, x, y);
1364
1361
vo_get_src_dst_rects(vo, &p->src_rect, &p->dst_rect, &p->osd_res);
1410
1407
params.chrom_texh = params.texh >> desc.chroma_ys;
1411
1408
params.csp_params.input_bits = depth;
1412
1409
params.csp_params.texture_bits = depth+7 & ~7;
1413
glSetupYUVConversion(gl, ¶ms);
1410
glSetupYUVConversion(vo, gl, ¶ms);
1414
1411
if (p->custom_prog) {
1415
1412
FILE *f = fopen(p->custom_prog, "rb");
1417
mp_msg(MSGT_VO, MSGL_WARN,
1418
"[gl] Could not read customprog %s\n", p->custom_prog);
1414
MP_WARN(vo, "Could not read customprog %s\n", p->custom_prog);
1420
1416
char *prog = calloc(1, MAX_CUSTOM_PROG_SIZE + 1);
1421
1417
fread(prog, 1, MAX_CUSTOM_PROG_SIZE, f);
1423
loadGPUProgram(gl, GL_FRAGMENT_PROGRAM, prog);
1419
loadGPUProgram(vo, gl, GL_FRAGMENT_PROGRAM, prog);
1426
1422
gl->ProgramEnvParameter4f(GL_FRAGMENT_PROGRAM, 0,
1431
1427
if (p->custom_tex) {
1432
1428
FILE *f = fopen(p->custom_tex, "rb");
1434
mp_msg(MSGT_VO, MSGL_WARN,
1435
"[gl] Could not read customtex %s\n", p->custom_tex);
1430
MP_WARN(vo, "Could not read customtex %s\n", p->custom_tex);
1437
1432
int width, height, maxval;
1438
1433
gl->ActiveTexture(GL_TEXTURE3);
1443
1438
1.0 / width, 1.0 / height,
1444
1439
width, height);
1446
mp_msg(MSGT_VO, MSGL_WARN,
1447
"[gl] Error parsing customtex %s\n", p->custom_tex);
1441
MP_WARN(vo, "Error parsing customtex %s\n", p->custom_tex);
1449
1443
gl->ActiveTexture(GL_TEXTURE0);
1531
1525
const char *renderer = gl->GetString(GL_RENDERER);
1532
1526
int is_ati = vendor && strstr(vendor, "ATI") != NULL;
1533
1527
int ati_broken_pbo = 0;
1534
mp_msg(MSGT_VO, MSGL_V, "[gl] Running on OpenGL '%s' by '%s', version '%s'\n",
1535
renderer, vendor, version);
1528
MP_VERBOSE(vo, "Running on OpenGL '%s' by '%s', version '%s'\n",
1529
renderer, vendor, version);
1536
1530
if (is_ati && strncmp(version, "2.1.", 4) == 0) {
1537
1531
int ver = atoi(version + 4);
1538
mp_msg(MSGT_VO, MSGL_V, "[gl] Detected ATI driver version: %i\n", ver);
1532
MP_VERBOSE(vo, "Detected ATI driver version: %i\n", ver);
1539
1533
ati_broken_pbo = ver && ver < 8395;
1541
1535
if (p->ati_hack == -1)
1582
1576
: GL_TEXTURE_INTENSITY_SIZE;
1583
1577
GLint size = 8;
1584
1578
gl->GetTexLevelParameteriv(target, 0, tex_size_token, &size);
1585
mp_msg(MSGT_VO, MSGL_V, "[gl] 16 bit texture depth: %d.\n", size);
1579
MP_VERBOSE(vo, "16 bit texture depth: %d.\n", size);
1586
1580
p->max_tex_component_size = size;
1589
1583
if (is_ati && (p->lscale == 1 || p->lscale == 2 || p->cscale == 1 || p->cscale == 2))
1590
mp_msg(MSGT_VO, MSGL_WARN, "[gl] Selected scaling mode may be broken on"
1592
"Tell _them_ to fix GL_REPEAT if you have issues.\n");
1593
mp_msg(MSGT_VO, MSGL_V, "[gl] Settings after autodetection: ati-hack = %i, "
1594
"force-pbo = %i, rectangle = %i, yuv = %i\n",
1595
p->ati_hack, p->force_pbo, p->use_rectangle, p->use_yuv);
1584
MP_WARN(vo, "Selected scaling mode may be broken on"
1585
" ATI cards.\nTell _them_ to fix GL_REPEAT if you have issues.\n");
1586
MP_VERBOSE(vo, "Settings after autodetection: ati-hack = %i, "
1587
"force-pbo = %i, rectangle = %i, yuv = %i\n",
1588
p->ati_hack, p->force_pbo, p->use_rectangle, p->use_yuv);
1598
1591
static GLint get_scale_type(struct vo *vo, int chroma)
1638
1631
gl->DrawBuffer(GL_BACK);
1639
1632
gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1641
mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
1642
p->texture_width, p->texture_height);
1634
MP_VERBOSE(vo, "Creating %dx%d texture...\n",
1635
p->texture_width, p->texture_height);
1644
1637
glCreateClearTex(gl, p->target, p->texfmt, p->gl_format,
1645
1638
p->gl_type, scale_type,
1682
1675
if (p->is_yuv || p->custom_prog) {
1683
1676
if ((MASK_NOT_COMBINERS & (1 << p->use_yuv)) || p->custom_prog) {
1684
1677
if (!gl->GenPrograms || !gl->BindProgram)
1685
mp_msg(MSGT_VO, MSGL_ERR,
1686
"[gl] fragment program functions missing!\n");
1678
MP_ERR(vo, "fragment program functions missing!\n");
1688
1680
gl->GenPrograms(1, &p->fragprog);
1689
1681
gl->BindProgram(GL_FRAGMENT_PROGRAM, p->fragprog);
1821
1813
int needed_size;
1822
1814
if (!gl->GenBuffers || !gl->BindBuffer || !gl->BufferData || !gl->MapBuffer) {
1823
1815
if (!p->err_shown)
1824
mp_msg(MSGT_VO, MSGL_ERR, "[gl] extensions missing for dr\n"
1825
"Expect a _major_ speed penalty\n");
1816
MP_ERR(vo, "extensions missing for dr\nExpect a _major_ speed penalty\n");
1826
1817
p->err_shown = 1;
1851
1842
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1852
1843
if (!mpi->planes[0]) {
1853
1844
if (!p->err_shown)
1854
mp_msg(MSGT_VO, MSGL_ERR, "[gl] could not acquire buffer for dr\n"
1845
MP_ERR(vo, "could not acquire buffer for dr\n"
1855
1846
"Expect a _major_ speed penalty\n");
1856
1847
p->err_shown = 1;
2082
2073
struct gl_priv *p = vo->priv;
2084
2075
if (p->use_yuv == 1) {
2085
mp_msg(MSGT_VO, MSGL_WARN, "[gl] yuv=1 (nVidia register combiners) have"
2086
" been removed, using yuv=2 instead.\n");
2076
MP_WARN(vo, "yuv=1 (nVidia register combiners) have"
2077
" been removed, using yuv=2 instead.\n");
2087
2078
p->use_yuv = 2;
2098
2089
autodetectGlExtensions(vo);
2100
mp_msg(MSGT_VO, MSGL_V, "[gl] Using %d as slice height "
2101
"(0 means image height).\n", p->slice_height);
2091
MP_VERBOSE(vo, "Using %d as slice height "
2092
"(0 means image height).\n", p->slice_height);