static xe_tex *create_texture(render_primitive *prim) { int j, k, l, x, y, tx, ty, bpp; int flag = PRIMFLAG_GET_TEXFORMAT(prim->flags); int rawwidth = prim->texture.width; int rawheight = prim->texture.height; // int width = ((rawwidth + 3) & (~3)); // int height = ((rawheight + 3) & (~3)); int width = ((rawwidth)); int height = ((rawheight)); // first the width if (width & (width - 1)) { width |= width >> 1; width |= width >> 2; width |= width >> 4; width |= width >> 8; width++; }
static int drawdd_window_draw(win_window_info *window, HDC dc, int update) { dd_info *dd = window->drawdata; const render_primitive *prim; int usemembuffer = FALSE; HRESULT result; // if we haven't been created, just punt if (dd == NULL) return 1; // if we're updating, remember to erase the outer stuff if (update) update_outer_rects(dd); // if we have a ddraw object, check the cooperative level if (ddraw_test_cooperative(window)) return 1; // get the size; if we're too small, delete the existing surfaces if (dd->blitwidth > dd->blitdesc.dwWidth || dd->blitheight > dd->blitdesc.dwHeight) ddraw_delete_surfaces(window); // if we need to create surfaces, do it now if (dd->blit == NULL && ddraw_create_surfaces(window) != 0) return 1; // select our surface and lock it result = IDirectDrawSurface7_Lock(dd->blit, NULL, &dd->blitdesc, DDLOCK_WAIT, NULL); if (result == DDERR_SURFACELOST) { mame_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n"); ddraw_delete_surfaces(window); return 1; } if (result != DD_OK) { mame_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result); return 1; } // render to it osd_lock_acquire(window->primlist->lock); // scan the list of primitives for tricky stuff for (prim = window->primlist->head; prim != NULL; prim = prim->next) if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE || (prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32)) { usemembuffer = TRUE; break; } // if we're using the memory buffer, draw offscreen first and then copy if (usemembuffer) { int x, y; // based on the target format, use one of our standard renderers switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask) { case 0x00ff0000: drawdd_rgb888_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; case 0x000000ff: drawdd_bgr888_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; case 0xf800: drawdd_rgb565_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; case 0x7c00: drawdd_rgb555_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; default: mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask); break; } // handle copying to both 16bpp and 32bpp destinations for (y = 0; y < dd->blitheight; y++) { if (dd->blitdesc.ddpfPixelFormat.dwRGBBitCount == 32) { UINT32 *src = (UINT32 *)dd->membuffer + y * dd->blitwidth; UINT32 *dst = (UINT32 *)((UINT8 *)dd->blitdesc.lpSurface + y * dd->blitdesc.lPitch); for (x = 0; x < dd->blitwidth; x++) *dst++ = *src++; } else if (dd->blitdesc.ddpfPixelFormat.dwRGBBitCount == 16) { UINT16 *src = (UINT16 *)dd->membuffer + y * dd->blitwidth; UINT16 *dst = (UINT16 *)((UINT8 *)dd->blitdesc.lpSurface + y * dd->blitdesc.lPitch); for (x = 0; x < dd->blitwidth; x++) *dst++ = *src++; } } } // otherwise, draw directly else { // based on the target format, use one of our standard renderers switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask) { case 0x00ff0000: drawdd_rgb888_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; case 0x000000ff: drawdd_bgr888_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; case 0xf800: drawdd_rgb565_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; case 0x7c00: drawdd_rgb555_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; default: mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask); break; } } osd_lock_release(window->primlist->lock); // unlock and blit result = IDirectDrawSurface7_Unlock(dd->blit, NULL); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result); // sync to VBLANK if ((video_config.waitvsync || video_config.syncrefresh) && video_get_throttle() && (!window->fullscreen || dd->back == NULL)) { result = IDirectDraw7_WaitForVerticalBlank(dd->ddraw, DDWAITVB_BLOCKBEGIN, NULL); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result); } // complete the blitting blit_to_primary(window, dd->blitwidth, dd->blitheight); return 0; }
texture_info::texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags) { // fill in the core data m_renderer = renderer; m_hash = texture_compute_hash(texsource, flags); m_flags = flags; m_texinfo = texsource; m_texinfo.seqid = -1; // force set data m_is_rotated = false; m_setup = setup; m_sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags)); m_pitch = 0; switch (PRIMFLAG_GET_TEXFORMAT(flags)) { case TEXFORMAT_ARGB32: m_format = SDL_TEXFORMAT_ARGB32; break; case TEXFORMAT_RGB32: m_format = texsource.palette ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32; break; case TEXFORMAT_PALETTE16: m_format = SDL_TEXFORMAT_PALETTE16; break; case TEXFORMAT_PALETTEA16: m_format = SDL_TEXFORMAT_PALETTE16A; break; case TEXFORMAT_YUY16: m_format = texsource.palette ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16; break; default: osd_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags)); } if (setup.rotwidth != m_texinfo.width || setup.rotheight != m_texinfo.height || setup.dudx < 0 || setup.dvdy < 0 || (PRIMFLAG_GET_TEXORIENT(flags) != 0)) m_is_rotated = true; else m_is_rotated = false; //m_sdl_access = SDL_TEXTUREACCESS_STATIC; m_sdl_access = SDL_TEXTUREACCESS_STREAMING; // Watch out for 0x0 textures ... if (!m_setup.rotwidth || !m_setup.rotheight) osd_printf_warning("Trying to create texture with zero dim\n"); // set copy_info m_copyinfo = compute_size_type(); m_texture_id = SDL_CreateTexture(m_renderer->m_sdl_renderer, m_copyinfo->dst_fmt, m_sdl_access, m_setup.rotwidth, m_setup.rotheight); if (!m_texture_id) osd_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", m_setup.rotwidth, m_setup.rotheight, m_copyinfo->dstname, SDL_GetError()); if (m_sdl_access == SDL_TEXTUREACCESS_STATIC) { if (m_copyinfo->blitter->m_is_passthrough) m_pixels = nullptr; else m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->blitter->m_dest_bpp); } m_last_access = osd_ticks(); }
static texture_info *texture_create(sdl_window_info *window, const render_texinfo *texsource, quad_setup_data *setup, UINT32 flags) { sdl_info *sdl = (sdl_info *) window->dxdata; texture_info *texture; // allocate a new texture texture = (texture_info *) osd_malloc(sizeof(*texture)); memset(texture, 0, sizeof(*texture)); // fill in the core data texture->hash = texture_compute_hash(texsource, flags); texture->flags = flags; texture->texinfo = *texsource; texture->texinfo.seqid = -1; // force set data texture->is_rotated = FALSE; texture->setup = *setup; texture->sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags)); switch (PRIMFLAG_GET_TEXFORMAT(flags)) { case TEXFORMAT_ARGB32: texture->format = SDL_TEXFORMAT_ARGB32; break; case TEXFORMAT_RGB32: texture->format = texsource->palette ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32; break; case TEXFORMAT_PALETTE16: texture->format = SDL_TEXFORMAT_PALETTE16; break; case TEXFORMAT_PALETTEA16: texture->format = SDL_TEXFORMAT_PALETTE16A; break; case TEXFORMAT_YUY16: texture->format = texsource->palette ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16; break; default: mame_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags)); } texture->rawwidth = texsource->width; texture->rawheight = texsource->height; if (setup->rotwidth != texture->rawwidth || setup->rotheight != texture->rawheight || setup->dudx < 0 ) texture->is_rotated = TRUE; else texture->is_rotated = FALSE; //texture->sdl_access = SDL_TEXTUREACCESS_STATIC; texture->sdl_access = SDL_TEXTUREACCESS_STREAMING; // Watch out for 0x0 textures ... if (!texture->setup.rotwidth || !texture->setup.rotheight) mame_printf_warning("Trying to create texture with zero dim\n"); // compute the size texture->copyinfo = texture_compute_size_type(sdl->sdl_renderer, texsource, texture, flags); texture->texture_id = SDL_CreateTexture(sdl->sdl_renderer, texture->copyinfo->dst_fmt, texture->sdl_access, texture->setup.rotwidth, texture->setup.rotheight); if (!texture->texture_id) mame_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", texture->setup.rotwidth, texture->setup.rotheight, texture->copyinfo->dstname, SDL_GetError()); if ( (texture->copyinfo->func != NULL) && (texture->sdl_access == SDL_TEXTUREACCESS_STATIC)) { texture->pixels = osd_malloc_array(texture->setup.rotwidth * texture->setup.rotheight * texture->copyinfo->dst_bpp); texture->pixels_own=TRUE; } /* add us to the texture list */ texture->next = sdl->texlist; sdl->texlist = texture; texture->last_access = osd_ticks(); return texture; }
int renderer_dd::draw(const int update) { render_primitive *prim; int usemembuffer = FALSE; HRESULT result; // if we're updating, remember to erase the outer stuff if (update) update_outer_rects(); // if we have a ddraw object, check the cooperative level if (ddraw_test_cooperative()) return 1; // get the size; if we're too small, delete the existing surfaces if (blitwidth > blitdesc.dwWidth || blitheight > blitdesc.dwHeight) ddraw_delete_surfaces(); // if we need to create surfaces, do it now if (blit == NULL && ddraw_create_surfaces() != 0) return 1; // select our surface and lock it result = IDirectDrawSurface7_Lock(blit, NULL, &blitdesc, DDLOCK_WAIT, NULL); if (result == DDERR_SURFACELOST) { osd_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n"); ddraw_delete_surfaces(); return 1; } if (result != DD_OK) { osd_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result); return 1; } // render to it window().m_primlist->acquire_lock(); // scan the list of primitives for tricky stuff for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next()) if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE || (prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32)) { usemembuffer = TRUE; break; } // if we're using the memory buffer, draw offscreen first and then copy if (usemembuffer) { int x, y; // based on the target format, use one of our standard renderers switch (blitdesc.ddpfPixelFormat.dwRBitMask) { case 0x00ff0000: software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break; case 0x000000ff: software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break; case 0xf800: software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break; case 0x7c00: software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth); break; default: osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask); break; } // handle copying to both 16bpp and 32bpp destinations for (y = 0; y < blitheight; y++) { if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 32) { UINT32 *src = (UINT32 *)membuffer + y * blitwidth; UINT32 *dst = (UINT32 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch); for (x = 0; x < blitwidth; x++) *dst++ = *src++; } else if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 16) { UINT16 *src = (UINT16 *)membuffer + y * blitwidth; UINT16 *dst = (UINT16 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch); for (x = 0; x < blitwidth; x++) *dst++ = *src++; } } } // otherwise, draw directly else { // based on the target format, use one of our standard renderers switch (blitdesc.ddpfPixelFormat.dwRBitMask) { case 0x00ff0000: software_renderer<UINT32, 0,0,0, 16,8,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break; case 0x000000ff: software_renderer<UINT32, 0,0,0, 0,8,16, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break; case 0xf800: software_renderer<UINT16, 3,2,3, 11,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break; case 0x7c00: software_renderer<UINT16, 3,3,3, 10,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break; default: osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask); break; } } window().m_primlist->release_lock(); // unlock and blit result = IDirectDrawSurface7_Unlock(blit, NULL); if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result); // sync to VBLANK if ((video_config.waitvsync || video_config.syncrefresh) && window().machine().video().throttled() && (!window().fullscreen() || back == NULL)) { result = IDirectDraw7_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKBEGIN, NULL); if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result); } // complete the blitting blit_to_primary(blitwidth, blitheight); return 0; }