static void surface_init(glw_video_t *gv, glw_video_surface_t *gvs) { int i; int siz[3]; surface_reset(gv, gvs); for(i = 0; i < 3; i++) siz[i] = ROUND_UP(gvs->gvs_width[i] * gvs->gvs_height[i], 16); gvs->gvs_size = siz[0] + siz[1] + siz[2]; gvs->gvs_offset = rsx_alloc(gvs->gvs_size, 16); gvs->gvs_data[0] = rsx_to_ppu(gvs->gvs_offset); gvs->gvs_data[1] = rsx_to_ppu(gvs->gvs_offset + siz[0]); gvs->gvs_data[2] = rsx_to_ppu(gvs->gvs_offset + siz[0] + siz[1]); int offset = gvs->gvs_offset; for(i = 0; i < 3; i++) { init_tex(&gvs->gvs_tex[i], offset, gvs->gvs_width[i], gvs->gvs_height[i], gvs->gvs_width[i], NV30_3D_TEX_FORMAT_FORMAT_I8, 0, NV30_3D_TEX_SWIZZLE_S0_X_S1 | NV30_3D_TEX_SWIZZLE_S0_Y_S1 | NV30_3D_TEX_SWIZZLE_S0_Z_S1 | NV30_3D_TEX_SWIZZLE_S0_W_S1 | NV30_3D_TEX_SWIZZLE_S1_X_X | NV30_3D_TEX_SWIZZLE_S1_Y_Y | NV30_3D_TEX_SWIZZLE_S1_Z_Z | NV30_3D_TEX_SWIZZLE_S1_W_W ); offset += siz[i]; } }
static void surface_init(glw_video_t *gv, glw_video_surface_t *gvs, const glw_video_config_t *gvc) { int i; int siz[3]; for(i = 0; i < 3; i++) siz[i] = ROUND_UP(gvc->gvc_width[i] * gvc->gvc_height[i], 16); gvs->gvs_size = siz[0] + siz[1] + siz[2]; gvs->gvs_offset = rsx_alloc(gvs->gvs_size, 16); gvs->gvs_data[0] = rsx_to_ppu(gvs->gvs_offset); gvs->gvs_data[1] = rsx_to_ppu(gvs->gvs_offset + siz[0]); gvs->gvs_data[2] = rsx_to_ppu(gvs->gvs_offset + siz[0] + siz[1]); int offset = gvs->gvs_offset; for(i = 0; i < 3; i++) { init_tex(&gvs->gvs_tex[i], offset, gvc->gvc_width[i], gvc->gvc_height[i], gvc->gvc_width[i], NV30_3D_TEX_FORMAT_FORMAT_I8, 0, NV30_3D_TEX_SWIZZLE_S0_X_S1 | NV30_3D_TEX_SWIZZLE_S0_Y_S1 | NV30_3D_TEX_SWIZZLE_S0_Z_S1 | NV30_3D_TEX_SWIZZLE_S0_W_S1 | NV30_3D_TEX_SWIZZLE_S1_X_X | NV30_3D_TEX_SWIZZLE_S1_Y_Y | NV30_3D_TEX_SWIZZLE_S1_Z_Z | NV30_3D_TEX_SWIZZLE_S1_W_W ); offset += siz[i]; } TAILQ_INSERT_TAIL(&gv->gv_avail_queue, gvs, gvs_link); }
static void surface_init(glw_video_t *gv, glw_video_surface_t *gvs, const glw_video_config_t *gvc) { glw_root_t *gr = gv->w.glw_root; int i; for(i = 0; i < 3; i++) { gvs->gvs_size[i] = gvc->gvc_width[i] * gvc->gvc_height[i]; gvs->gvs_offset[i] = rsx_alloc(gr, gvs->gvs_size[i], 16); gvs->gvs_data[i] = rsx_to_ppu(gr, gvs->gvs_offset[i]); init_tex(&gvs->gvs_tex[i], gvs->gvs_offset[i], gvc->gvc_width[i], gvc->gvc_height[i], gvc->gvc_width[i], NV30_3D_TEX_FORMAT_FORMAT_I8, 0, NV30_3D_TEX_SWIZZLE_S0_X_S1 | NV30_3D_TEX_SWIZZLE_S0_Y_S1 | NV30_3D_TEX_SWIZZLE_S0_Z_S1 | NV30_3D_TEX_SWIZZLE_S0_W_S1 | NV30_3D_TEX_SWIZZLE_S1_X_X | NV30_3D_TEX_SWIZZLE_S1_Y_Y | NV30_3D_TEX_SWIZZLE_S1_Z_Z | NV30_3D_TEX_SWIZZLE_S1_W_W ); } TAILQ_INSERT_TAIL(&gv->gv_avail_queue, gvs, gvs_link); }
static pixmap_t * rsx_read_pixels(glw_root_t *gr) { glw_ps3_t *gp = (glw_ps3_t *)gr; pixmap_t *pm = pixmap_create(gr->gr_width, gr->gr_height, PIXMAP_RGBA, 0); memcpy(pm->pm_data, rsx_to_ppu(gp->framebuffer[0]), pm->pm_linesize * pm->pm_height); return pm; }
static void picture_out(vdec_decoder_t *vdd) { int r, lumasize; uint32_t addr; vdec_picture_format picfmt; vdec_pic_t *vp; char metainfo[64]; pktmeta_t *pm; picfmt.alpha = 0; picfmt.format_type = VDEC_PICFMT_YUV420P; picfmt.color_matrix = VDEC_COLOR_MATRIX_BT709; r = vdec_get_pic_item(vdd->handle, &addr); if(r != 0) return; vdec_picture *pi = (void *)(intptr_t)addr; pm = &vdd->pktmeta[pi->userdata[0]]; vdd->pending_flush |= pm->flush; if(/* pi->status != 0 ||*/ pi->attr != 0 || pm->skip) { vdec_get_picture(vdd->handle, &picfmt, NULL); reset_active_pictures(vdd, "pic err", 0); return; } if(vdd->pending_flush) { reset_active_pictures(vdd, "stream flush", 0); vdd->pending_flush = 0; vdd->max_order = -1; } int64_t pts = pm->nopts ? AV_NOPTS_VALUE : pi->pts[0].low + ((uint64_t)pi->pts[0].hi << 32); int64_t dts = pm->nodts ? AV_NOPTS_VALUE : pi->dts[0].low + ((uint64_t)pi->dts[0].hi << 32); int64_t order; if(pi->codec_type == VDEC_CODEC_TYPE_MPEG2) { vdec_mpeg2_info *mpeg2 = (void *)(intptr_t)pi->codec_specific_addr; lumasize = mpeg2->width * mpeg2->height; vp = alloc_picture(vdd, lumasize); vp->fi.fi_width = mpeg2->width; vp->fi.fi_height = mpeg2->height; vp->fi.fi_duration = mpeg2->frame_rate <= 8 ? mpeg_durations[mpeg2->frame_rate] : 40000; if(pm->disable_deinterlacer) { vp->fi.fi_interlaced = 0; } else { vp->fi.fi_interlaced = !mpeg2->progressive_frame; vp->fi.fi_tff = mpeg2->top_field_first; } if(mpeg2->color_description) vp->fi.fi_color_space = mpeg2->matrix_coefficients; switch(pm->aspect_override) { default: switch(mpeg2->aspect_ratio) { case VDEC_MPEG2_ARI_SAR_1_1: vp->fi.fi_dar_num = mpeg2->width; vp->fi.fi_dar_den = mpeg2->height; break; case VDEC_MPEG2_ARI_DAR_4_3: vp->fi.fi_dar_num = 4; vp->fi.fi_dar_den = 3; break; case VDEC_MPEG2_ARI_DAR_16_9: vp->fi.fi_dar_num = 16; vp->fi.fi_dar_den = 9; break; case VDEC_MPEG2_ARI_DAR_2P21_1: vp->fi.fi_dar_num = 221; vp->fi.fi_dar_den = 100; break; } break; case 1: vp->fi.fi_dar_num = 4; vp->fi.fi_dar_den = 3; break; case 2: vp->fi.fi_dar_num = 16; vp->fi.fi_dar_den = 9; break; } snprintf(metainfo, sizeof(metainfo), "MPEG2 %dx%d%c (Cell)", mpeg2->width, mpeg2->height, vp->fi.fi_interlaced ? 'i' : 'p'); if(pts == AV_NOPTS_VALUE && dts != AV_NOPTS_VALUE && mpeg2->picture_coding_type[0] == 3) pts = dts; #if VDEC_DETAILED_DEBUG TRACE(TRACE_DEBUG, "VDEC DEC", "%ld %d", pts, mpeg2->picture_coding_type[0]); #endif order = vdd->order_base; vdd->order_base++; } else { vdec_h264_info *h264 = (void *)(intptr_t)pi->codec_specific_addr; lumasize = h264->width * h264->height; vp = alloc_picture(vdd, lumasize); vp->fi.fi_width = h264->width; vp->fi.fi_height = h264->height; vp->fi.fi_duration = h264->frame_rate <= 7 ? mpeg_durations[h264->frame_rate + 1] : 40000; vp->fi.fi_interlaced = 0; vp->fi.fi_tff = 0; if(h264->color_description_present_flag) vp->fi.fi_color_space = h264->matrix_coefficients; vp->fi.fi_dar_num = h264->width; vp->fi.fi_dar_den = h264->height; if(h264->aspect_ratio_idc == 0xff) { vp->fi.fi_dar_num *= h264->sar_width; vp->fi.fi_dar_den *= h264->sar_height; } else { const uint8_t *p; p = h264_sar[h264->aspect_ratio_idc <= 16 ? h264->aspect_ratio_idc : 0]; vp->fi.fi_dar_num *= p[0]; vp->fi.fi_dar_den *= p[1]; } if(h264->idr_picture_flag) { vdd->order_base += 0x100000000LL; vdd->poc_ext = 0; } uint32_t om = h264->pic_order_count[0] & 0x7fff; int p = om >> 13; if(p == ((vdd->poc_ext + 1) & 3)) { vdd->poc_ext = p; if(p == 0) vdd->order_base += 0x100000000LL; } if(p == 3 && vdd->poc_ext == 0) { order = vdd->order_base + om - 0x100000000LL; } else { order = vdd->order_base + om; } if(pts == AV_NOPTS_VALUE && dts != AV_NOPTS_VALUE) { if(h264->picture_type[0] == 2) { vdd->seen_b_frames = 100; pts = dts; } if(vdd->seen_b_frames) vdd->seen_b_frames--; if(!vdd->seen_b_frames) pts = dts; } #if VDEC_DETAILED_DEBUG TRACE(TRACE_DEBUG, "VDEC DEC", "POC=%3d:%-3d IDR=%d PS=%d LD=%d %x 0x%llx %ld %d", (uint16_t)h264->pic_order_count[0], (uint16_t)h264->pic_order_count[1], h264->idr_picture_flag, h264->pic_struct, h264->low_delay_hrd_flag, h264->nalUnitPresentFlags, order, pts, h264->picture_type[0]); #endif if(vdd->level_major) snprintf(metainfo, sizeof(metainfo), "h264 (Level %d.%d) %dx%d%c (Cell)", vdd->level_major, vdd->level_minor, h264->width, h264->height, vp->fi.fi_interlaced ? 'i' : 'p'); else snprintf(metainfo, sizeof(metainfo), "h264 %dx%d%c (Cell)", h264->width, h264->height, vp->fi.fi_interlaced ? 'i' : 'p'); } prop_set_string(vdd->metainfo, metainfo); vp->fi.fi_pix_fmt = PIX_FMT_YUV420P; vp->fi.fi_pts = pts; vp->fi.fi_epoch = pm->epoch; vp->fi.fi_prescaled = 0; vp->fi.fi_color_space = COLOR_SPACE_UNSET; vp->fi.fi_delta = pm->delta; vp->fi.fi_drive_clock = pm->drive_clock; vdec_get_picture(vdd->handle, &picfmt, rsx_to_ppu(vp->vp_offset)); vp->order = order; hts_mutex_lock(&vdd->mtx); LIST_INSERT_SORTED(&vdd->pictures, vp, link, vp_cmp); if(vdd->max_order != -1) { if(vp->order > vdd->max_order) { vdd->flush_to = vdd->max_order; vdd->max_order = vp->order; } } else { vdd->max_order = vp->order; } hts_mutex_unlock(&vdd->mtx); }
static rsx_fp_t * load_fp(glw_root_t *gr, const char *url) { char errmsg[100]; realityFragmentProgram *fp; int i; const char *name; if((fp = fa_load(url, NULL, NULL, errmsg, sizeof(errmsg), NULL)) == NULL) { TRACE(TRACE_ERROR, "glw", "Unable to load shader %s -- %s\n", url, log); return NULL; } TRACE(TRACE_INFO, "glw", "Loaded fragment program %s", url); TRACE(TRACE_INFO, "glw", " num regs: %d", fp->num_regs); realityProgramConst *constants; constants = realityFragmentProgramGetConsts(fp); for(i = 0; i < fp->num_const; i++) { if(constants[i].name_off) name = ((char*)fp)+constants[i].name_off; else name = "<anon>"; TRACE(TRACE_INFO, "glw", " Constant %s @ 0x%x [%f, %f, %f, %f] type=%d", name, constants[i].index, constants[i].values[0].f, constants[i].values[1].f, constants[i].values[2].f, constants[i].values[3].f, constants[i].type); } realityProgramAttrib *attributes; attributes = realityFragmentProgramGetAttribs(fp); for(i = 0; i < fp->num_attrib; i++) { if(attributes[i].name_off) name = ((char*)fp)+attributes[i].name_off; else name = "<anon>"; TRACE(TRACE_INFO, "glw", " Attribute %s @ 0x%x", name, attributes[i].index); } int offset = rsx_alloc(gr, fp->num_insn * 16, 256); uint32_t *buf = rsx_to_ppu(gr, offset); TRACE(TRACE_INFO, "glw", " PPU location: 0x%08x %d bytes", buf, fp->num_insn * 16); const uint32_t *src = (uint32_t *)((char*)fp + fp->ucode_off); memcpy(buf, src, fp->num_insn * 16); TRACE(TRACE_INFO, "glw", " RSX location: 0x%08x", offset); rsx_fp_t *rfp = calloc(1, sizeof(rsx_fp_t)); rfp->rfp_binary = fp; rfp->rfp_rsx_location = offset; rfp->rfp_u_color = realityFragmentProgramGetConst(fp, "u_color"); rfp->rfp_u_color_matrix = realityFragmentProgramGetConst(fp, "u_colormtx"); rfp->rfp_u_blend = realityFragmentProgramGetConst(fp, "u_blend"); for(i = 0; i < 6; i++) { char name[8]; snprintf(name, sizeof(name), "u_t%d", i); rfp->rfp_texunit[i] = realityFragmentProgramGetAttrib(fp, name); if(rfp->rfp_texunit[i] != -1) TRACE(TRACE_INFO, "glw", " Texture %d via unit %d", i, rfp->rfp_texunit[i]); } return rfp; }