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) { 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) { 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); }
/** * yuv420 only */ static vdec_pic_t * alloc_picture(vdec_decoder_t *vdd, int lumasize) { vdec_pic_t *vp = malloc(sizeof(vdec_pic_t)); vp->vp_size = lumasize + lumasize / 2; vp->vp_offset = rsx_alloc(vp->vp_size, 16); if(vp->vp_offset == -1) panic("Cell decoder out of RSX memory"); return vp; }
/** * yuv420 only */ static vdec_pic_t * alloc_picture(vdec_decoder_t *vdd, int width, int height) { vdec_pic_t *vp = malloc(sizeof(vdec_pic_t)); int lumasize = width * height; vp->fi.fi_pitch[0] = width; vp->fi.fi_pitch[1] = width / 2; vp->fi.fi_pitch[2] = width / 2; vp->vp_size = lumasize + lumasize / 2; vp->vp_offset[0] = rsx_alloc(vp->vp_size, 16); if(vp->vp_offset[0] == -1) panic("Cell decoder out of RSX memory. Unable to alloc %d bytes", vp->vp_size); vp->vp_offset[1] = vp->vp_offset[0] + lumasize; vp->vp_offset[2] = vp->vp_offset[1] + lumasize / 4; return vp; }
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; }
static void init_screen(glw_ps3_t *gp) { // Allocate a 1Mb buffer, alligned to a 1Mb boundary to be our shared IO memory with the RSX. void *host_addr = memalign(1024*1024, 1024*1024); assert(host_addr != NULL); // Initilise Reality, which sets up the command buffer and shared IO memory gp->gr.gr_be.be_ctx = realityInit(0x10000, 1024*1024, host_addr); assert(gp->gr.gr_be.be_ctx != NULL); gcmConfiguration config; gcmGetConfiguration(&config); TRACE(TRACE_INFO, "RSX", "memory @ 0x%x size = %d\n", config.localAddress, config.localSize); hts_mutex_init(&gp->gr.gr_be.be_mempool_lock); gp->gr.gr_be.be_mempool = extent_create(0, config.localSize >> 4); gp->gr.gr_be.be_rsx_address = (void *)(uint64_t)config.localAddress; VideoState state; videoGetState(0, 0, &state); // Get the current resolution videoGetResolution(state.displayMode.resolution, &gp->res); int num = gp->res.width; int den = gp->res.height; switch(state.displayMode.aspect) { case VIDEO_ASPECT_4_3: num = 4; den = 3; break; case VIDEO_ASPECT_16_9: num = 16; den = 9; break; } gp->scale = (float)(num * gp->res.height) / (float)(den * gp->res.width); TRACE(TRACE_INFO, "RSX", "Video resolution %d x %d aspect=%d, pixel wscale=%f", gp->res.width, gp->res.height, state.displayMode.aspect, gp->scale); gp->framebuffer_pitch = 4 * gp->res.width; // each pixel is 4 bytes gp->depthbuffer_pitch = 4 * gp->res.width; // And each value in the depth buffer is a 16 bit float // Configure the buffer format to xRGB VideoConfiguration vconfig; memset(&vconfig, 0, sizeof(VideoConfiguration)); vconfig.resolution = state.displayMode.resolution; vconfig.format = VIDEO_BUFFER_FORMAT_XRGB; vconfig.pitch = gp->framebuffer_pitch; videoConfigure(0, &vconfig, NULL, 0); videoGetState(0, 0, &state); const s32 buffer_size = gp->framebuffer_pitch * gp->res.height; const s32 depth_buffer_size = gp->depthbuffer_pitch * gp->res.height; TRACE(TRACE_INFO, "RSX", "Buffer will be %d bytes", buffer_size); gcmSetFlipMode(GCM_FLIP_VSYNC); // Wait for VSYNC to flip // Allocate two buffers for the RSX to draw to the screen (double buffering) gp->framebuffer[0] = rsx_alloc(&gp->gr, buffer_size, 16); gp->framebuffer[1] = rsx_alloc(&gp->gr, buffer_size, 16); TRACE(TRACE_INFO, "RSX", "Buffers at 0x%x 0x%x\n", gp->framebuffer[0], gp->framebuffer[1]); gp->depthbuffer = rsx_alloc(&gp->gr, depth_buffer_size * 4, 16); // Setup the display buffers gcmSetDisplayBuffer(0, gp->framebuffer[0], gp->framebuffer_pitch, gp->res.width, gp->res.height); gcmSetDisplayBuffer(1, gp->framebuffer[1], gp->framebuffer_pitch, gp->res.width, gp->res.height); gcmResetFlipStatus(); flip(gp, 1); }