diff options
-rw-r--r-- | src/mame/drivers/indy_indigo2.cpp | 24 | ||||
-rw-r--r-- | src/mame/machine/sgi.cpp | 176 | ||||
-rw-r--r-- | src/mame/machine/sgi.h | 12 | ||||
-rw-r--r-- | src/mame/video/newport.cpp | 358 | ||||
-rw-r--r-- | src/mame/video/newport.h | 10 |
5 files changed, 420 insertions, 160 deletions
diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp index 882b167bad7..39d1386aced 100644 --- a/src/mame/drivers/indy_indigo2.cpp +++ b/src/mame/drivers/indy_indigo2.cpp @@ -61,7 +61,7 @@ #include "emu.h" -#include "cpu/mips/mips3.h" +#include "cpu/mips/r4000.h" #include "machine/hpc3.h" #include "machine/nscsi_bus.h" @@ -107,7 +107,7 @@ protected: static void scsi_devices(device_slot_interface &device); - required_device<mips3_device> m_maincpu; + required_device<cpu_device> m_maincpu; required_shared_ptr<uint64_t> m_mainram; required_device<sgi_mc_device> m_mem_ctrl; required_device<wd33c93b_device> m_scsi_ctrl; @@ -173,7 +173,7 @@ void ip22_state::machine_reset() // set up low RAM mirror membank("bank1")->set_base(m_mainram); - m_maincpu->mips3drc_set_options(MIPS3DRC_COMPATIBLE_OPTIONS | MIPS3DRC_CHECK_OVERFLOWS); + //m_maincpu->mips3drc_set_options(MIPS3DRC_COMPATIBLE_OPTIONS | MIPS3DRC_CHECK_OVERFLOWS); } static INPUT_PORTS_START( ip225015 ) @@ -238,9 +238,9 @@ void ip22_state::ip225015(machine_config &config) { ip22_base(config); - R5000BE(config, m_maincpu, 50000000*3); - m_maincpu->set_icache_size(32768); - m_maincpu->set_dcache_size(32768); + R4000(config, m_maincpu, 50000000*3); + //m_maincpu->set_icache_size(32768); + //m_maincpu->set_dcache_size(32768); m_maincpu->set_addrmap(AS_PROGRAM, &ip22_state::ip22_map); SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl); @@ -250,9 +250,9 @@ void ip22_state::ip224613(machine_config &config) { ip22_base(config); - R4600BE(config, m_maincpu, 33333333*4); - m_maincpu->set_icache_size(32768); - m_maincpu->set_dcache_size(32768); + R4600(config, m_maincpu, 33333333*4); + //m_maincpu->set_icache_size(32768); + //m_maincpu->set_dcache_size(32768); m_maincpu->set_addrmap(AS_PROGRAM, &ip22_state::ip22_map); SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl); @@ -269,9 +269,9 @@ void ip24_state::ip244415(machine_config &config) { ip22_base(config); - R4400BE(config, m_maincpu, 50000000*3); - m_maincpu->set_icache_size(32768); - m_maincpu->set_dcache_size(32768); + R4400(config, m_maincpu, 50000000*3); + //m_maincpu->set_icache_size(32768); + //m_maincpu->set_dcache_size(32768); m_maincpu->set_addrmap(AS_PROGRAM, &ip24_state::ip22_map); NSCSI_BUS(config, "scsibus2", 0); diff --git a/src/mame/machine/sgi.cpp b/src/mame/machine/sgi.cpp index 9eb08b76321..9e458778a78 100644 --- a/src/mame/machine/sgi.cpp +++ b/src/mame/machine/sgi.cpp @@ -19,9 +19,10 @@ #define LOG_MEMCFG (1 << 5) #define LOG_MEMCFG_EXT (1 << 6) #define LOG_EEPROM (1 << 7) +#define LOG_DMA (1 << 8) #define LOG_DEFAULT (LOG_READS | LOG_WRITES | LOG_RPSS | LOG_WATCHDOG | LOG_UNKNOWN) -#define VERBOSE (0) +#define VERBOSE (LOG_DMA) #include "logmacro.h" DEFINE_DEVICE_TYPE(SGI_MC, sgi_mc_device, "sgi_mc", "SGI Memory Controller") @@ -52,14 +53,6 @@ sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, dev , m_gio64_substitute_bits(0) , m_dma_int_cause(0) , m_dma_control(0) - , m_dma_tlb_entry0_hi(0) - , m_dma_tlb_entry0_lo(0) - , m_dma_tlb_entry1_hi(0) - , m_dma_tlb_entry1_lo(0) - , m_dma_tlb_entry2_hi(0) - , m_dma_tlb_entry2_lo(0) - , m_dma_tlb_entry3_hi(0) - , m_dma_tlb_entry3_lo(0) , m_rpss_counter(0) , m_dma_mem_addr(0) , m_dma_size(0) @@ -117,14 +110,8 @@ void sgi_mc_device::device_start() save_item(NAME(m_gio64_substitute_bits)); save_item(NAME(m_dma_int_cause)); save_item(NAME(m_dma_control)); - save_item(NAME(m_dma_tlb_entry0_hi)); - save_item(NAME(m_dma_tlb_entry0_lo)); - save_item(NAME(m_dma_tlb_entry1_hi)); - save_item(NAME(m_dma_tlb_entry1_lo)); - save_item(NAME(m_dma_tlb_entry2_hi)); - save_item(NAME(m_dma_tlb_entry2_lo)); - save_item(NAME(m_dma_tlb_entry3_hi)); - save_item(NAME(m_dma_tlb_entry3_lo)); + save_item(NAME(m_dma_tlb_entry_hi)); + save_item(NAME(m_dma_tlb_entry_lo)); save_item(NAME(m_rpss_counter)); save_item(NAME(m_dma_mem_addr)); save_item(NAME(m_dma_size)); @@ -166,14 +153,11 @@ void sgi_mc_device::device_reset() m_gio64_substitute_bits = 0; m_dma_int_cause = 0; m_dma_control = 0; - m_dma_tlb_entry0_hi = 0; - m_dma_tlb_entry0_lo = 0; - m_dma_tlb_entry1_hi = 0; - m_dma_tlb_entry1_lo = 0; - m_dma_tlb_entry2_hi = 0; - m_dma_tlb_entry2_lo = 0; - m_dma_tlb_entry3_hi = 0; - m_dma_tlb_entry3_lo = 0; + for (int i = 0; i < 4; i++) + { + m_dma_tlb_entry_hi[i] = 0; + m_dma_tlb_entry_lo[i] = 0; + } m_rpss_counter = 0; m_dma_mem_addr = 0; m_dma_size = 0; @@ -200,6 +184,19 @@ void sgi_mc_device::set_cpu_buserr(uint32_t address) m_cpu_error_status |= 0x0000000f; } +uint32_t sgi_mc_device::dma_translate(uint32_t address) +{ + for (int entry = 0; entry < 4; entry++) + { + if ((address & 0xfff00000) == (m_dma_tlb_entry_hi[entry] & 0xfff00000)) + { + const uint32_t offset = address - m_dma_tlb_entry_hi[entry]; + return ((m_dma_tlb_entry_lo[entry] &~ 0x3f) << 6) + offset; + } + } + return 0; +} + READ32_MEMBER(sgi_mc_device::read) { switch (offset & ~1) @@ -283,63 +280,63 @@ READ32_MEMBER(sgi_mc_device::read) LOGMASKED(LOG_READS, "%s: GIO64 Translation Address Substitution Bits Read: %08x & %08x\n", machine().describe_context(), m_gio64_substitute_bits, mem_mask); return m_gio64_substitute_bits; case 0x0160/4: - LOGMASKED(LOG_READS, "%s: DMA Interrupt Cause: %08x & %08x\n", machine().describe_context(), m_dma_int_cause, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Interrupt Cause: %08x & %08x\n", machine().describe_context(), m_dma_int_cause, mem_mask); return m_dma_int_cause; case 0x0168/4: - LOGMASKED(LOG_READS, "%s: DMA Control Read: %08x & %08x\n", machine().describe_context(), m_dma_control, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Control Read: %08x & %08x\n", machine().describe_context(), m_dma_control, mem_mask); return m_dma_control; case 0x0180/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 0 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry0_hi, mem_mask); - return m_dma_tlb_entry0_hi; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 0 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[0], mem_mask); + return m_dma_tlb_entry_hi[0]; case 0x0188/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 0 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry0_lo, mem_mask); - return m_dma_tlb_entry0_lo; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 0 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[0], mem_mask); + return m_dma_tlb_entry_lo[0]; case 0x0190/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 1 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry1_hi, mem_mask); - return m_dma_tlb_entry1_hi; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 1 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[1], mem_mask); + return m_dma_tlb_entry_hi[1]; case 0x0198/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 1 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry1_lo, mem_mask); - return m_dma_tlb_entry1_lo; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 1 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[1], mem_mask); + return m_dma_tlb_entry_lo[1]; case 0x01a0/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 2 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry2_hi, mem_mask); - return m_dma_tlb_entry2_hi; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 2 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[2], mem_mask); + return m_dma_tlb_entry_hi[2]; case 0x01a8/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 2 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry2_lo, mem_mask); - return m_dma_tlb_entry2_lo; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 2 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[2], mem_mask); + return m_dma_tlb_entry_lo[2]; case 0x01b0/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 3 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry3_hi, mem_mask); - return m_dma_tlb_entry3_hi; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 3 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[3], mem_mask); + return m_dma_tlb_entry_hi[3]; case 0x01b8/4: - LOGMASKED(LOG_READS, "%s: DMA TLB Entry 3 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry3_lo, mem_mask); - return m_dma_tlb_entry3_lo; + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 3 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[3], mem_mask); + return m_dma_tlb_entry_lo[3]; case 0x1000/4: LOGMASKED(LOG_RPSS, "%s: RPSS 100ns Counter Read: %08x & %08x\n", machine().describe_context(), m_rpss_counter, mem_mask); return m_rpss_counter; case 0x2000/4: case 0x2008/4: - LOGMASKED(LOG_READS, "%s: DMA Memory Address Read: %08x & %08x\n", machine().describe_context(), m_dma_mem_addr, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Memory Address Read: %08x & %08x\n", machine().describe_context(), m_dma_mem_addr, mem_mask); return m_dma_mem_addr; case 0x2010/4: - LOGMASKED(LOG_READS, "%s: DMA Line Count and Width Read: %08x & %08x\n", machine().describe_context(), m_dma_size, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Line Count and Width Read: %08x & %08x\n", machine().describe_context(), m_dma_size, mem_mask); return m_dma_size; case 0x2018/4: - LOGMASKED(LOG_READS, "%s: DMA Line Zoom and Stride Read: %08x & %08x\n", machine().describe_context(), m_dma_stride, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Line Zoom and Stride Read: %08x & %08x\n", machine().describe_context(), m_dma_stride, mem_mask); return m_dma_stride; case 0x2020/4: case 0x2028/4: - LOGMASKED(LOG_READS, "%s: DMA GIO64 Address Read: %08x & %08x\n", machine().describe_context(), m_dma_gio64_addr, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA GIO64 Address Read: %08x & %08x\n", machine().describe_context(), m_dma_gio64_addr, mem_mask); return m_dma_gio64_addr; case 0x2030/4: - LOGMASKED(LOG_READS, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), m_dma_mode, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), m_dma_mode, mem_mask); return m_dma_mode; case 0x2038/4: - LOGMASKED(LOG_READS, "%s: DMA Zoom Count Read: %08x & %08x\n", machine().describe_context(), m_dma_count, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Zoom Count Read: %08x & %08x\n", machine().describe_context(), m_dma_count, mem_mask); return m_dma_count; case 0x2040/4: - LOGMASKED(LOG_READS, "%s: DMA Start Read\n", machine().describe_context()); + LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Start Read\n", machine().describe_context()); return 0; case 0x2048/4: - LOGMASKED(LOG_READS, "%s: VDMA Running Read: %08x & %08x\n", machine().describe_context(), m_dma_running, mem_mask); + LOGMASKED(LOG_READS | LOG_DMA, "%s: VDMA Running Read: %08x & %08x\n", machine().describe_context(), m_dma_running, mem_mask); if (m_dma_running == 1) { m_dma_running = 0; @@ -486,86 +483,105 @@ WRITE32_MEMBER( sgi_mc_device::write ) m_gio64_substitute_bits = data; break; case 0x0160/4: - LOGMASKED(LOG_WRITES, "%s: DMA Interrupt Cause Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Interrupt Cause Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_int_cause = data; break; case 0x0168/4: - LOGMASKED(LOG_WRITES, "%s: DMA Control Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Control Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); m_dma_control = data; break; case 0x0180/4: - LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 0 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_dma_tlb_entry0_hi = data; + LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 0 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_dma_tlb_entry_hi[0] = data; break; case 0x0188/4: - LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 0 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_dma_tlb_entry0_lo = data; + LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 0 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_dma_tlb_entry_lo[0] = data; break; case 0x0190/4: - LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 1 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); - m_dma_tlb_entry1_hi = data; + LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 1 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_dma_tlb_entry_hi[1] = data; break; case 0x0198/4: - LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 1 Low Wri // license:BSD-3-Clause
// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
// drawsdl.c - SDL software and OpenGL implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
// yuvmodes by Couriersud
//
//============================================================
// standard C headers
#include <math.h>
#include <stdio.h>
// MAME headers
#include "emu.h"
#include "ui/ui.h"
#include "rendersw.inc"
// standard SDL headers
#include "sdlinc.h"
// OSD headers
#include "osdsdl.h"
#include "window.h"
#include "drawsdl.h"
//============================================================
// DEBUGGING
//============================================================
//============================================================
// CONSTANTS
//============================================================
#define DRAW2_SCALEMODE_NEAREST "0"
#define DRAW2_SCALEMODE_LINEAR "1"
#define DRAW2_SCALEMODE_BEST "2"
//============================================================
// PROTOTYPES
//============================================================
// YUV overlays
static void yuv_RGB_to_YV12(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height);
static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height);
static void yuv_RGB_to_YUY2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height);
static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height);
// Static declarations
static const sdl_scale_mode scale_modes[] =
{
{ "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, 0 },
{ "hwblit", 1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, 0 },
{ "hwbest", 1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, 0 },
/* SDL1.2 uses interpolation as well */
{ "yv12", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
{ "yv12x2", 1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
{ "yuy2", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
{ "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
{ nullptr }
};
int drawsdl_scale_mode(const char *s)
{
const sdl_scale_mode *sm = scale_modes;
int index;
index = 0;
while (sm->name != nullptr)
{
if (strcmp(sm->name, s) == 0)
return index;
index++;
sm++;
}
return -1;
}
//============================================================
// drawsdl_init
//============================================================
bool renderer_sdl2::init(running_machine &machine)
{
osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
return false;
}
//============================================================
// setup_texture for window
//============================================================
void renderer_sdl2::setup_texture(const osd_dim &size)
{
const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
SDL_DisplayMode mode;
UINT32 fmt;
// Determine preferred pixelformat and set up yuv if necessary
SDL_GetCurrentDisplayMode(*((UINT64 *)window().monitor()->oshandle()), &mode);
if (m_yuv_bitmap)
{
global_free_array(m_yuv_bitmap);
m_yuv_bitmap = nullptr;
}
fmt = (sdl_sm->pixel_format ? sdl_sm->pixel_format : mode.format);
if (sdl_sm->is_scale)
{
int m_hw_scale_width = 0;
int m_hw_scale_height = 0;
window().target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
if (window().prescale())
{
m_hw_scale_width *= window().prescale();
m_hw_scale_height *= window().prescale();
/* This must be a multiple of 2 */
m_hw_scale_width = (m_hw_scale_width + 1) & ~1;
}
if (sdl_sm->is_yuv)
m_yuv_bitmap = global_alloc_array(UINT16, m_hw_scale_width * m_hw_scale_height);
int w = m_hw_scale_width * sdl_sm->mult_w;
int h = m_hw_scale_height * sdl_sm->mult_h;
m_texture_id = SDL_CreateTexture(m_sdl_renderer, fmt, SDL_TEXTUREACCESS_STREAMING, w, h);
}
else
{
m_texture_id = SDL_CreateTexture(m_sdl_renderer,fmt, SDL_TEXTUREACCESS_STREAMING,
size.width(), size.height());
}
}
//============================================================
// drawsdl_show_info
//============================================================
void renderer_sdl2::show_info(struct SDL_RendererInfo *render_info)
{
#define RF_ENTRY(x) {x, #x }
static struct
{
int flag;
const char *name;
} rflist[] =
{
#if 0
RF_ENTRY(SDL_RENDERER_SINGLEBUFFER),
RF_ENTRY(SDL_RENDERER_PRESENTCOPY),
RF_ENTRY(SDL_RENDERER_PRESENTFLIP2),
RF_ENTRY(SDL_RENDERER_PRESENTFLIP3),
RF_ENTRY(SDL_RENDERER_PRESENTDISCARD),
#endif
RF_ENTRY(SDL_RENDERER_PRESENTVSYNC),
RF_ENTRY(SDL_RENDERER_ACCELERATED),
{-1, nullptr}
};
osd_printf_verbose("window: using renderer %s\n", render_info->name ? render_info->name : "<unknown>");
for (int i = 0; rflist[i].name != nullptr; i++)
if (render_info->flags & rflist[i].flag)
osd_printf_verbose("renderer: flag %s\n", rflist[i].name);
}
//============================================================
// renderer_sdl2::create
//============================================================
int renderer_sdl2::create()
{
const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
// create renderer
/* set hints ... */
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, sm->sdl_scale_mode_hint);
if (video_config.waitvsync)
m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
else
m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_ACCELERATED);
if (!m_sdl_renderer)
{
if (video_config.waitvsync)
m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE);
else
m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_SOFTWARE);
}
if (!m_sdl_renderer)
{
fatalerror("Error on creating renderer: %s\n", SDL_GetError());
}
struct SDL_RendererInfo render_info;
SDL_GetRendererInfo(m_sdl_renderer, &render_info);
show_info(&render_info);
// Check scale mode
if (sm->pixel_format)
{
int i;
int found = 0;
for (i=0; i < render_info.num_texture_formats; i++)
if (sm->pixel_format == render_info.texture_formats[i])
found = 1;
if (!found)
{
fatalerror("window: Scale mode %s not supported!", sm->name);
}
}
#if 0
int w = 0, h = 0;
window().get_size(w, h);
setup_texture(w, h);
#endif
m_yuv_lookup = nullptr;
m_blittimer = 0;
yuv_init();
osd_printf_verbose("Leave renderer_sdl2::create\n");
return 0;
}
//============================================================
// DESTRUCTOR
//============================================================
renderer_sdl2::~renderer_sdl2()
{
destroy_all_textures();
if (m_yuv_lookup != nullptr)
{
global_free_array(m_yuv_lookup);
m_yuv_lookup = nullptr;
}
if (m_yuv_bitmap != nullptr)
{
global_free_array(m_yuv_bitmap);
m_yuv_bitmap = nullptr;
}
SDL_DestroyRenderer(m_sdl_renderer);
}
//============================================================
// drawsdl_xy_to_render_target
//============================================================
int renderer_sdl2::xy_to_render_target(int x, int y, int *xt, int *yt)
{
*xt = x - m_last_hofs;
*yt = y - m_last_vofs;
if (*xt<0 || *xt >= m_blit_dim.width())
return 0;
if (*yt<0 || *yt >= m_blit_dim.height())
return 0;
return 1;
}
//============================================================
// drawsdl_destroy_all_textures
//============================================================
void renderer_sdl2::destroy_all_textures()
{
SDL_DestroyTexture(m_texture_id);
m_texture_id = nullptr;
}
//============================================================
// renderer_sdl2::draw
//============================================================
int renderer_sdl2::draw(int update)
{
const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
UINT8 *surfptr;
INT32 pitch;
Uint32 rmask, gmask, bmask;
Uint32 amask;
INT32 vofs, hofs, blitwidth, blitheight, ch, cw;
int bpp;
if (video_config.novideo)
{
return 0;
}
osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim != m_last_dim))
{
destroy_all_textures();
clear_flags(FI_CHANGED);
m_blittimer = 3;
m_last_dim = wdim;
SDL_RenderSetViewport(m_sdl_renderer, nullptr);
if (m_texture_id != nullptr)
SDL_DestroyTexture(m_texture_id);
setup_texture(m_blit_dim);
m_blittimer = 3;
}
// lock it if we need it
{
Uint32 format;
int access, w, h;
SDL_QueryTexture(m_texture_id, &format, &access, &w, &h);
SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask);
bpp = bpp / 8; /* convert to bytes per pixels */
}
// Clear if necessary
if (m_blittimer > 0)
{
/* SDL Underlays need alpha = 0 ! */
SDL_SetRenderDrawColor(m_sdl_renderer,0,0,0,0);
SDL_RenderFillRect(m_sdl_renderer,nullptr);
//SDL_RenderFill(0,0,0,0 /*255*/,nullptr);
m_blittimer--;
}
SDL_LockTexture(m_texture_id, nullptr, (void **) &surfptr, &pitch);
// get ready to center the image
vofs = hofs = 0;
blitwidth = m_blit_dim.width();
blitheight = m_blit_dim.height();
ch = wdim.height();
cw = wdim.width();
// do not crash if the window's smaller than the blit area
if (blitheight > ch)
{
blitheight = ch;
}
else if (video_config.centerv)
{
vofs = (ch - m_blit_dim.height()) / 2;
}
if (blitwidth > cw)
{
blitwidth = cw;
}
else if (video_config.centerh)
{
hofs = (cw - m_blit_dim.width()) / 2;
}
m_last_hofs = hofs;
m_last_vofs = vofs;
window().m_primlist->acquire_lock();
int mamewidth, mameheight;
Uint32 fmt = 0;
int access = 0;
SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight);
mamewidth /= sm->mult_w;
mameheight /= sm->mult_h;
//printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight);
// rescale bounds
float fw = (float) mamewidth / (float) blitwidth;
float fh = (float) mameheight / (float) blitheight;
// FIXME: this could be a lot easier if we get the primlist here!
// Bounds would be set fit for purpose and done!
for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next())
{
prim->bounds.x0 = floor(fw * prim->bounds.x0 + 0.5f);
prim->bounds.x1 = floor(fw * prim->bounds.x1 + 0.5f);
prim->bounds.y0 = floor(fh * prim->bounds.y0 + 0.5f);
prim->bounds.y1 = floor(fh * prim->bounds.y1 + 0.5f);
}
// render to it
if (!sm->is_yuv)
{
switch (rmask)
{
case 0x0000ff00:
software_renderer<UINT32, 0,0,0, 8,16,24>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x00ff0000:
software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x000000ff:
software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0xf800:
software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
case 0x7c00:
software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
default:
osd_printf_error("SDL: ERROR! Unknown video mode: R=%08X G=%08X B=%08X\n", rmask, gmask, bmask);
break;
}
}
else
{
assert (m_yuv_bitmap != nullptr);
assert (surfptr != nullptr);
software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap, mamewidth, mameheight, mamewidth);
sm->yuv_blit((UINT16 *)m_yuv_bitmap, surfptr, pitch, m_yuv_lookup, mamewidth, mameheight);
}
window().m_primlist->release_lock();
// unlock and flip
SDL_UnlockTexture(m_texture_id);
{
SDL_Rect r;
r.x=hofs;
r.y=vofs;
r.w=blitwidth;
r.h=blitheight;
//printf("blitwidth %d %d - %d %d\n", blitwidth, blitheight, window().width, window().height);
//SDL_UpdateTexture(sdltex, nullptr, sdlsurf->pixels, pitch);
SDL_RenderCopy(m_sdl_renderer,m_texture_id, nullptr, &r);
SDL_RenderPresent(m_sdl_renderer);
}
return 0;
}
//============================================================
// YUV Blitting
//============================================================
#define CU_CLAMP(v, a, b) ((v < a)? a: ((v > b)? b: v))
#define RGB2YUV_F(r,g,b,y,u,v) \
(y) = (0.299*(r) + 0.587*(g) + 0.114*(b) ); \
(u) = (-0.169*(r) - 0.331*(g) + 0.5*(b) + 128); \
(v) = (0.5*(r) - 0.419*(g) - 0.081*(b) + 128); \
(y) = CU_CLAMP(y,0,255); \
(u) = CU_CLAMP(u,0,255); \
(v) = CU_CLAMP(v,0,255)
#define RGB2YUV(r,g,b,y,u,v) \
(y) = (( 8453*(r) + 16594*(g) + 3223*(b) + 524288) >> 15); \
(u) = (( -4878*(r) - 9578*(g) + 14456*(b) + 4210688) >> 15); \
(v) = (( 14456*(r) - 12105*(g) - 2351*(b) + 4210688) >> 15)
#ifdef LSB_FIRST
#define Y1MASK 0x000000FF
#define UMASK 0x0000FF00
#define Y2MASK 0x00FF0000
#define VMASK 0xFF000000
#define Y1SHIFT 0
#define USHIFT 8
#define Y2SHIFT 16
#define VSHIFT 24
#else
#define Y1MASK 0xFF000000
#define UMASK 0x00FF0000
#define Y2MASK 0x0000FF00
#define VMASK 0x000000FF
#define Y1SHIFT 24
#define USHIFT 16
#define Y2SHIFT 8
#define VSHIFT 0
#endif
#define YMASK (Y1MASK|Y2MASK)
#define UVMASK (UMASK|VMASK)
void renderer_sdl2::yuv_lookup_set(unsigned int pen, unsigned char red,
unsigned char green, unsigned char blue)
{
UINT32 y,u,v;
RGB2YUV(red,green,blue,y,u,v);
/* Storing this data in YUYV order simplifies using the data for
YUY2, both with and without smoothing... */
m_yuv_lookup[pen]=(y<<Y1SHIFT)|(u<<USHIFT)|(y<<Y2SHIFT)|(v<<VSHIFT);
}
void renderer_sdl2::yuv_init()
{
unsigned char r,g,b;
if (m_yuv_lookup == nullptr)
m_yuv_lookup = global_alloc_array(UINT32, 65536);
for (r = 0; r < 32; r++)
for (g = 0; g < 32; g++)
for (b = 0; b < 32; b++)
{
int idx = (r << 10) | (g << 5) | b;
yuv_lookup_set(idx,
(r << 3) | (r >> 2),
(g << 3) | (g >> 2),
(b << 3) | (b >> 2));
}
}
//UINT32 *lookup = sdl->m_yuv_lookup;
static void yuv_RGB_to_YV12(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height)
{
int x, y;
UINT8 *pixels[3];
int u1,v1,y1,u2,v2,y2,u3,v3,y3,u4,v4,y4; /* 12 */
pixels[0] = ptr;
pixels[1] = ptr + pitch * height;
pixels[2] = pixels[1] + pitch * height / 4;
for(y=0;y<height;y+=2)
{
const UINT16 *src=bitmap + (y * width) ;
const UINT16 *src2=src + width;
UINT8 *dest_y = pixels[0] + y * pitch;
UINT8 *dest_v = pixels[1] + (y>>1) * pitch / 2;
UINT8 *dest_u = pixels[2] + (y>>1) * pitch / 2;
for(x=0;x<width;x+=2)
{
v1 = lookup[src[x]];
y1 = (v1>>Y1SHIFT) & 0xff;
u1 = (v1>>USHIFT) & 0xff;
v1 = (v1>>VSHIFT) & 0xff;
v2 = lookup[src[x+1]];
y2 = (v2>>Y1SHIFT) & 0xff;
u2 = (v2>>USHIFT) & 0xff;
v2 = (v2>>VSHIFT) & 0xff;
v3 = lookup[src2[x]];
y3 = (v3>>Y1SHIFT) & 0xff;
u3 = (v3>>USHIFT) & 0xff;
v3 = (v3>>VSHIFT) & 0xff;
v4 = lookup[src2[x+1]];
y4 = (v4>>Y1SHIFT) & 0xff;
u4 = (v4>>USHIFT) & 0xff;
v4 = (v4>>VSHIFT) & 0xff;
dest_y[x] = y1;
dest_y[x+pitch] = y3;
dest_y[x+1] = y2;
dest_y[x+pitch+1] = y4;
dest_u[x>>1] = (u1+u2+u3+u4)/4;
dest_v[x>>1] = (v1+v2+v3+v4)/4;
}
}
}
static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height)
{
/* this one is used when scale==2 */
unsigned int x,y;
int u1,v1,y1;
UINT8 *pixels[3];
pixels[0] = ptr;
pixels[1] = ptr + pitch * height * 2;
int p2 = (pitch >> 1);
pixels[2] = pixels[1] + p2 * height;
for(y=0;y<height;y++)
{
const UINT16 *src = bitmap + (y * width) ;
UINT16 *dest_y = (UINT16 *)(pixels[0] + 2 * y * pitch);
UINT8 *dest_v = pixels[1] + y * p2;
UINT8 *dest_u = pixels[2] + y * p2;
for(x=0;x<width;x++)
{
v1 = lookup[src[x]];
y1 = (v1 >> Y1SHIFT) & 0xff;
u1 = (v1 >> USHIFT) & 0xff;
v1 = (v1 >> VSHIFT) & 0xff;
dest_y[x + pitch/2] = y1 << 8 | y1;
dest_y[x] = y1 << 8 | y1;
dest_u[x] = u1;
dest_v[x] = v1;
}
}
}
static void yuv_RGB_to_YUY2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height)
{
/* this one is used when scale==2 */
unsigned int y;
UINT32 p1,p2,uv;
const int yuv_pitch = pitch/4;
for(y=0;y<height;y++)
{
const UINT16 *src=bitmap + (y * width) ;
const UINT16 *end=src+width;
UINT32 *dest = (UINT32 *) ptr;
dest += y * yuv_pitch;
for(; src<end; src+=2)
{
p1 = lookup[src[0]];
p2 = lookup[src[1]];
uv = (p1&UVMASK)>>1;
uv += (p2&UVMASK)>>1;
*dest++ = (p1&Y1MASK)|(p2&Y2MASK)|(uv&UVMASK);
}
}
}
static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
const UINT32 *lookup, const int width, const int height)
{
/* this one is used when scale==2 */
unsigned int y;
int yuv_pitch = pitch / 4;
for(y=0;y<height;y++)
{
const UINT16 *src=bitmap + (y * width) ;
const UINT16 *end=src+width;
UINT32 *dest = (UINT32 *) ptr;
dest += (y * yuv_pitch);
for(; src<end; src++)
{
dest[0] = lookup[src[0]];
dest++;
}
}
}
render_primitive_list *renderer_sdl2::get_primitives()
{
osd_dim nd = window().blit_surface_size();
if (nd != m_blit_dim)
{
m_blit_dim = nd;
notify_changed();
}
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
return &window().target()->get_primitives();
}
|