diff options
author | 2016-03-23 17:55:55 +0100 | |
---|---|---|
committer | 2016-03-23 17:55:55 +0100 | |
commit | ba0a1d8d5218804bc1d5b09d5b3fa8fcd537f0bf (patch) | |
tree | 9fe5ca6f9f6352f724ea9a26fff5ebda23576607 /src/osd/modules/render/drawbgfx.cpp | |
parent | d0867ac3f2bdcfd4d1d2361ce8b6408a185908f4 (diff) | |
parent | 5ed9f938ea322d386e949d2752892651d9ee9fde (diff) |
Merge bgfx_shader into master, nw
Diffstat (limited to 'src/osd/modules/render/drawbgfx.cpp')
-rw-r--r-- | src/osd/modules/render/drawbgfx.cpp | 655 |
1 files changed, 395 insertions, 260 deletions
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 88257150abd..fd843b2a87f 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -23,6 +23,7 @@ // MAMEOS headers #include "emu.h" #include "window.h" +#include "rendutil.h" #include <bgfx/bgfxplatform.h> #include <bgfx/bgfx.h> @@ -31,6 +32,7 @@ #include <algorithm> #include "drawbgfx.h" +#include "copyutil.h" #include "bgfx/texturemanager.h" #include "bgfx/targetmanager.h" #include "bgfx/shadermanager.h" @@ -40,6 +42,9 @@ #include "bgfx/texture.h" #include "bgfx/target.h" #include "bgfx/chain.h" +#include "bgfx/vertex.h" +#include "bgfx/uniform.h" +#include "bgfx/slider.h" //============================================================ // DEBUGGING @@ -52,23 +57,20 @@ const uint16_t renderer_bgfx::CACHE_SIZE = 1024; const uint32_t renderer_bgfx::PACKABLE_SIZE = 128; const uint32_t renderer_bgfx::WHITE_HASH = 0x87654321; +const char* renderer_bgfx::WINDOW_PREFIX = "Window 0, "; //============================================================ // MACROS //============================================================ -#define GIBBERISH (0) +#define GIBBERISH (0) //============================================================ -// INLINES -//============================================================ - - -//============================================================ -// TYPES +// STATICS //============================================================ bool renderer_bgfx::s_window_set = false; +uint32_t renderer_bgfx::s_current_view = 0; //============================================================ // renderer_bgfx::create @@ -102,6 +104,7 @@ int renderer_bgfx::create() { // create renderer + osd_options& options = downcast<osd_options &>(window().machine().options()); osd_dim wdim = window().get_size(); m_width[window().m_index] = wdim.width(); m_height[window().m_index] = wdim.height(); @@ -124,25 +127,54 @@ int renderer_bgfx::create() #else bgfx::sdlSetWindow(window().sdl_window()); #endif - bgfx::init(); + std::string backend(options.bgfx_backend()); + if (backend == "auto") + { + bgfx::init(); + } + else if (backend == "dx9" || backend == "d3d9") + { + bgfx::init(bgfx::RendererType::Direct3D9); + } + else if (backend == "dx11" || backend == "d3d11") + { + bgfx::init(bgfx::RendererType::Direct3D11); + } + else if (backend == "gles") + { + bgfx::init(bgfx::RendererType::OpenGLES); + } + else if (backend == "glsl" || backend == "opengl") + { + bgfx::init(bgfx::RendererType::OpenGL); + } + else if (backend == "metal") + { + bgfx::init(bgfx::RendererType::Metal); + } + else + { + printf("Unknown backend type '%s', going with auto-detection\n", backend.c_str()); + bgfx::init(); + } bgfx::reset(m_width[window().m_index], m_height[window().m_index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); // Enable debug text. - bgfx::setDebug(window().machine().options().verbose() ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT); + bgfx::setDebug(options.bgfx_debug() ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT); m_dimensions = osd_dim(m_width[0], m_height[0]); } m_textures = new texture_manager(); - m_targets = new target_manager(*m_textures); - m_shaders = new shader_manager(); - m_effects = new effect_manager(*m_shaders); - m_chains = new chain_manager(*m_textures, *m_targets, *m_effects, m_width[window().m_index], m_height[window().m_index]); + m_targets = new target_manager(options, *m_textures); + + m_shaders = new shader_manager(options); + m_effects = new effect_manager(options, *m_shaders); if (window().m_index != 0) { #ifdef OSD_WINDOWS - m_framebuffer = m_targets->create_target("backbuffer", window().m_hwnd, m_width[window().m_index], m_height[window().m_index]); + m_framebuffer = m_targets->create_backbuffer(window().m_hwnd, m_width[window().m_index], m_height[window().m_index]); #else - m_framebuffer = m_targets->create_target("backbuffer", sdlNativeWindowHandle(window().sdl_window()), m_width[window().m_index], m_height[window().m_index]); + m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(window().sdl_window()), m_width[window().m_index], m_height[window().m_index]); #endif bgfx::touch(window().m_index); } @@ -158,18 +190,67 @@ int renderer_bgfx::create() m_screen_effect[2] = m_effects->effect("screen_multiply"); m_screen_effect[3] = m_effects->effect("screen_add"); - //m_screen_chain[0] = m_chains->chain("test"); + m_chains = new chain_manager(options, *m_textures, *m_targets, *m_effects, m_width[window().m_index], m_height[window().m_index]); + parse_screen_chains(options.bgfx_screen_chains()); + m_sliders_dirty = true; uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; m_texture_cache = m_textures->create_texture("#cache", bgfx::TextureFormat::RGBA8, CACHE_SIZE, CACHE_SIZE, nullptr, flags); - memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16); + uint32_t shadow_flags = 0;//BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; + m_textures->create_png_texture(window().machine().options().art_path(), options.bgfx_shadow_mask(), "shadow", shadow_flags); + + memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16); m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white)); return 0; } //============================================================ +// parse_screen_chains +//============================================================ + +void renderer_bgfx::parse_screen_chains(std::string chain_str) +{ + std::vector<std::vector<std::string>> chains; + uint32_t length = chain_str.length(); + uint32_t last_start = 0; + uint32_t win = 0; + chains.push_back(std::vector<std::string>()); + for (uint32_t i = 0; i < length + 1; i++) + { + if (i == length || chain_str[i] == ',' || chain_str[i] == ':') + { + chains[win].push_back(chain_str.substr(last_start, i - last_start)); + last_start = i + 1; + if (chain_str[i] == ':') + { + win++; + chains.push_back(std::vector<std::string>()); + } + } + } + + for (win = 0; win < chains.size(); win++) + { + m_screen_chains.push_back(std::vector<bgfx_chain*>()); + if (win != window().m_index) + { + continue; + } + for (uint32_t screen = 0; screen < chains[win].size(); screen++) + { + bgfx_chain* chain = m_chains->chain(chains[win][screen], window().machine(), win, screen); + if (chain == nullptr) { + chains.clear(); + return; + } + m_screen_chains[win].push_back(chain); + } + } +} + +//============================================================ // destructor //============================================================ @@ -210,7 +291,7 @@ int renderer_bgfx::xy_to_render_target(int x, int y, int *xt, int *yt) // drawbgfx_window_draw //============================================================ -bgfx::VertexDecl renderer_bgfx::ScreenVertex::ms_decl; +bgfx::VertexDecl ScreenVertex::ms_decl; void renderer_bgfx::put_packed_quad(render_primitive *prim, UINT32 hash, ScreenVertex* vertex) { @@ -295,9 +376,114 @@ void renderer_bgfx::put_packed_quad(render_primitive *prim, UINT32 hash, ScreenV vertex[5].m_v = v[0]; } +void renderer_bgfx::process_screen_quad(int screen, render_primitive* prim) +{ + uint32_t texture_flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP; + if (video_config.filter == 0) + { + texture_flags |= BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; + } + + uint16_t tex_width(prim->texture.width); + uint16_t tex_height(prim->texture.height); + + const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK, + tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base); + + bgfx_texture *texture = new bgfx_texture("screen", bgfx::TextureFormat::RGBA8, tex_width, tex_height, mem); + m_textures->add_provider("screen", texture); + + m_targets->update_guest_targets(screen, tex_width, tex_height); + + screen_chain(screen)->process(prim, s_current_view, screen, *m_textures, window(), get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags))); + s_current_view += screen_chain(screen)->applicable_passes(); + + m_textures->add_provider("screen", nullptr); + delete texture; +} + +void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer, int32_t screen) +{ + ScreenVertex* vertex = reinterpret_cast<ScreenVertex*>(buffer->data); + + float x[4] = { prim->bounds.x0, prim->bounds.x1, prim->bounds.x0, prim->bounds.x1 }; + float y[4] = { prim->bounds.y0, prim->bounds.y0, prim->bounds.y1, prim->bounds.y1 }; + float u[4] = { prim->texcoords.tl.u, prim->texcoords.tr.u, prim->texcoords.bl.u, prim->texcoords.br.u }; + float v[4] = { prim->texcoords.tl.v, prim->texcoords.tr.v, prim->texcoords.bl.v, prim->texcoords.br.v }; + + if (false)//PRIMFLAG_GET_TEXORIENT(prim->flags) & ORIENTATION_SWAP_XY) + { + std::swap(u[1], u[2]); + std::swap(v[1], v[2]); + } + + if (false)//PRIMFLAG_GET_TEXORIENT(prim->flags) & ORIENTATION_FLIP_X) + { + std::swap(u[0], u[1]); + std::swap(v[0], v[1]); + std::swap(u[2], u[3]); + std::swap(v[2], v[3]); + } + + if (false)//PRIMFLAG_GET_TEXORIENT(prim->flags) & ORIENTATION_FLIP_Y) + { + std::swap(u[0], u[2]); + std::swap(v[0], v[2]); + std::swap(u[1], u[3]); + std::swap(v[1], v[3]); + } + + vertex[0].m_x = x[0]; + vertex[0].m_y = y[0]; + vertex[0].m_z = 0; + vertex[0].m_rgba = 0xffffffff; + vertex[0].m_u = u[0]; + vertex[0].m_v = v[0]; + + vertex[1].m_x = x[1]; + vertex[1].m_y = y[1]; + vertex[1].m_z = 0; + vertex[1].m_rgba = 0xffffffff; + vertex[1].m_u = u[1]; + vertex[1].m_v = v[1]; + + vertex[2].m_x = x[3]; + vertex[2].m_y = y[3]; + vertex[2].m_z = 0; + vertex[2].m_rgba = 0xffffffff; + vertex[2].m_u = u[3]; + vertex[2].m_v = v[3]; + + vertex[3].m_x = x[3]; + vertex[3].m_y = y[3]; + vertex[3].m_z = 0; + vertex[3].m_rgba = 0xffffffff; + vertex[3].m_u = u[3]; + vertex[3].m_v = v[3]; + + vertex[4].m_x = x[2]; + vertex[4].m_y = y[2]; + vertex[4].m_z = 0; + vertex[4].m_rgba = 0xffffffff; + vertex[4].m_u = u[2]; + vertex[4].m_v = v[2]; + + vertex[5].m_x = x[0]; + vertex[5].m_y = y[0]; + vertex[5].m_z = 0; + vertex[5].m_rgba = 0xffffffff; + vertex[5].m_u = u[0]; + vertex[5].m_v = v[0]; + + UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags); + bgfx::setVertexBuffer(buffer); + bgfx::setTexture(0, m_screen_effect[blend]->uniform("s_tex")->handle(), m_targets->target("output" + std::to_string(screen))->texture()); + m_screen_effect[blend]->submit(view); +} + void renderer_bgfx::render_textured_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer) { - ScreenVertex* vertex = (ScreenVertex*)buffer->data; + ScreenVertex* vertex = reinterpret_cast<ScreenVertex*>(buffer->data); UINT32 rgba = u32Color(prim->color.r * 255, prim->color.g * 255, prim->color.b * 255, prim->color.a * 255); @@ -342,7 +528,6 @@ void renderer_bgfx::render_textured_quad(int view, render_primitive* prim, bgfx: vertex[5].m_rgba = rgba; vertex[5].m_u = prim->texcoords.tl.u; vertex[5].m_v = prim->texcoords.tl.v; - bgfx::setVertexBuffer(buffer); uint32_t texture_flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP; if (video_config.filter == 0) @@ -350,13 +535,18 @@ void renderer_bgfx::render_textured_quad(int view, render_primitive* prim, bgfx: texture_flags |= BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; } - const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK, - prim->texture.width, prim->texture.height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base); + uint16_t tex_width(prim->texture.width); + uint16_t tex_height(prim->texture.height); + + const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK, + tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base); - bgfx::TextureHandle texture = bgfx::createTexture2D((uint16_t)prim->texture.width, (uint16_t)prim->texture.height, 1, bgfx::TextureFormat::RGBA8, texture_flags, mem); + bgfx::TextureHandle texture = bgfx::createTexture2D(tex_width, tex_height, 1, bgfx::TextureFormat::RGBA8, texture_flags, mem); bgfx_effect** effects = PRIMFLAG_GET_SCREENTEX(prim->flags) ? m_screen_effect : m_gui_effect; + UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags); + bgfx::setVertexBuffer(buffer); bgfx::setTexture(0, effects[blend]->uniform("s_tex")->handle(), texture); effects[blend]->submit(view); @@ -552,176 +742,6 @@ uint32_t renderer_bgfx::u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a return (a << 24) | (b << 16) | (g << 8) | r; } -//============================================================ -// copyline_palette16 -//============================================================ - -static inline void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette) -{ - for (int x = 0; x < width; x++) - { - rgb_t srcpixel = palette[*src++]; - *dst++ = 0xff000000 | (srcpixel.b() << 16) | (srcpixel.g() << 8) | srcpixel.r(); - } -} - - -//============================================================ -// copyline_palettea16 -//============================================================ - -static inline void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette) -{ - for (int x = 0; x < width; x++) - { - rgb_t srcpixel = palette[*src++]; - *dst++ = (srcpixel.a() << 24) | (srcpixel.b() << 16) | (srcpixel.g() << 8) | srcpixel.r(); - } -} - - -//============================================================ -// copyline_rgb32 -//============================================================ - -static inline void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette) -{ - int x; - - // palette (really RGB map) case - if (palette != nullptr) - { - for (x = 0; x < width; x++) - { - rgb_t srcpix = *src++; - *dst++ = 0xff000000 | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()]; - } - } - - // direct case - else - { - for (x = 0; x < width; x++) - { - rgb_t srcpix = *src++; - *dst++ = 0xff000000 | (srcpix.b() << 16) | (srcpix.g() << 8) | srcpix.r(); - } - } -} - - -//============================================================ -// copyline_argb32 -//============================================================ - -static inline void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette) -{ - int x; - // palette (really RGB map) case - if (palette != nullptr) - { - for (x = 0; x < width; x++) - { - rgb_t srcpix = *src++; - *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()]; - } - } - - // direct case - else - { - for (x = 0; x < width; x++) - { - rgb_t srcpix = *src++; - *dst++ = (srcpix.a() << 24) | (srcpix.b() << 16) | (srcpix.g() << 8) | srcpix.r(); - } - } -} - -static inline UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) -{ - /* original equations: - - C = Y - 16 - D = Cb - 128 - E = Cr - 128 - - R = clip(( 298 * C + 409 * E + 128) >> 8) - G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) - B = clip(( 298 * C + 516 * D + 128) >> 8) - - R = clip(( 298 * (Y - 16) + 409 * (Cr - 128) + 128) >> 8) - G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8) - B = clip(( 298 * (Y - 16) + 516 * (Cb - 128) + 128) >> 8) - - R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) - G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) - B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) - - R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) - G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) - B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) - */ - int r, g, b, common; - - common = 298 * y - 298 * 16; - r = (common + 409 * cr - 409 * 128 + 128) >> 8; - g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8; - b = (common + 516 * cb - 516 * 128 + 128) >> 8; - - if (r < 0) r = 0; - else if (r > 255) r = 255; - if (g < 0) g = 0; - else if (g > 255) g = 255; - if (b < 0) b = 0; - else if (b > 255) b = 255; - - return 0xff000000 | (b << 16) | (g << 8) | r; -} - -//============================================================ -// copyline_yuy16_to_argb -//============================================================ - -static inline void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xprescale) -{ - int x; - - assert(width % 2 == 0); - - // palette (really RGB map) case - if (palette != nullptr) - { - for (x = 0; x < width / 2; x++) - { - UINT16 srcpix0 = *src++; - UINT16 srcpix1 = *src++; - UINT8 cb = srcpix0 & 0xff; - UINT8 cr = srcpix1 & 0xff; - for (int x2 = 0; x2 < xprescale; x2++) - *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr); - for (int x2 = 0; x2 < xprescale; x2++) - *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr); - } - } - - // direct case - else - { - for (x = 0; x < width; x += 2) - { - UINT16 srcpix0 = *src++; - UINT16 srcpix1 = *src++; - UINT8 cb = srcpix0 & 0xff; - UINT8 cr = srcpix1 & 0xff; - for (int x2 = 0; x2 < xprescale; x2++) - *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr); - for (int x2 = 0; x2 < xprescale; x2++) - *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr); - } - } -} - const bgfx::Memory* renderer_bgfx::mame_texture_data_to_bgfx_texture_data(UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base) { const bgfx::Memory* mem = bgfx::alloc(width * height * 4); @@ -730,19 +750,19 @@ const bgfx::Memory* renderer_bgfx::mame_texture_data_to_bgfx_texture_data(UINT32 switch (format) { case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16): - copyline_palette16((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette); + copy_util::copyline_palette16((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette); break; case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTEA16): - copyline_palettea16((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette); + copy_util::copyline_palettea16((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette); break; case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16): - copyline_yuy16_to_argb((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette, 1); + copy_util::copyline_yuy16_to_argb((UINT32*)mem->data + y * width, (UINT16*)base + y * rowpixels, width, palette, 1); break; case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32): - copyline_argb32((UINT32*)mem->data + y * width, (UINT32*)base + y * rowpixels, width, palette); + copy_util::copyline_argb32((UINT32*)mem->data + y * width, (UINT32*)base + y * rowpixels, width, palette); break; case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32): - copyline_rgb32((UINT32*)mem->data + y * width, (UINT32*)base + y * rowpixels, width, palette); + copy_util::copyline_rgb32((UINT32*)mem->data + y * width, (UINT32*)base + y * rowpixels, width, palette); break; default: break; @@ -751,67 +771,120 @@ const bgfx::Memory* renderer_bgfx::mame_texture_data_to_bgfx_texture_data(UINT32 return mem; } +int renderer_bgfx::handle_screen_chains() +{ + if (m_screen_chains.size() <= window().m_index || m_screen_chains[window().m_index].size() == 0) + { + return 0; + } + + window().m_primlist->acquire_lock(); + + render_primitive *prim = window().m_primlist->first(); + + // Determine how many post-processing passes are needed + int screens = 0; + while (prim != nullptr) + { + if (PRIMFLAG_GET_SCREENTEX(prim->flags)) + { + screens++; + } + prim = prim->next(); + } + m_targets->update_screen_count(screens); + + // Process each screen as necessary + prim = window().m_primlist->first(); + int seen_screen_quads = 0; + while (prim != nullptr) + { + if (PRIMFLAG_GET_SCREENTEX(prim->flags)) + { + process_screen_quad(seen_screen_quads, prim); + seen_screen_quads++; + } + prim = prim->next(); + } + + window().m_primlist->release_lock(); + + bgfx::setViewFrameBuffer(s_current_view, BGFX_INVALID_HANDLE); + + return s_current_view; +} + +bgfx_chain* renderer_bgfx::screen_chain(int32_t screen) +{ + if (screen >= m_screen_chains[window().m_index].size()) + { + return m_screen_chains[window().m_index][m_screen_chains[window().m_index].size() - 1]; + } + else + { + return m_screen_chains[window().m_index][screen]; + } +} + int renderer_bgfx::draw(int update) { - int index = window().m_index; - // Set view 0 default viewport. + int window_index = window().m_index; + if (window_index == 0) + { + s_current_view = 0; + } + + handle_screen_chains(); + int view_index = s_current_view; + + // Set view 0 default viewport. osd_dim wdim = window().get_size(); - m_width[index] = wdim.width(); - m_height[index] = wdim.height(); - if (index == 0) + m_width[window_index] = wdim.width(); + m_height[window_index] = wdim.height(); + if (window_index == 0) { - if ((m_dimensions != osd_dim(m_width[index], m_height[index]))) + if ((m_dimensions != osd_dim(m_width[window_index], m_height[window_index]))) { - bgfx::reset(m_width[index], m_height[index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); - m_dimensions = osd_dim(m_width[index], m_height[index]); + bgfx::reset(m_width[window_index], m_height[window_index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); + m_dimensions = osd_dim(m_width[window_index], m_height[window_index]); } } else { - if ((m_dimensions != osd_dim(m_width[index], m_height[index]))) + if ((m_dimensions != osd_dim(m_width[window_index], m_height[window_index]))) { bgfx::reset(window().m_main->get_size().width(), window().m_main->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); delete m_framebuffer; #ifdef OSD_WINDOWS - m_framebuffer = m_targets->create_target("backbuffer", window().m_hwnd, m_width[index], m_height[index]); + m_framebuffer = m_targets->create_backbuffer(window().m_hwnd, m_width[window_index], m_height[window_index]); #else - m_framebuffer = m_targets->create_target("backbuffer", sdlNativeWindowHandle(window().sdl_window()), m_width[index], m_height[index]); + m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(window().sdl_window()), m_width[window_index], m_height[window_index]); #endif - bgfx::setViewFrameBuffer(index, m_framebuffer->target()); - m_dimensions = osd_dim(m_width[index], m_height[index]); - bgfx::setViewClear(index + bgfx::setViewFrameBuffer(view_index, m_framebuffer->target()); + m_dimensions = osd_dim(m_width[window_index], m_height[window_index]); + bgfx::setViewClear(view_index , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH - , 0x000000ff + , 0x00ff00ff , 1.0f , 0 ); - bgfx::touch(index); + bgfx::touch(view_index); bgfx::frame(); return 0; } - } - if (index != 0) - { - bgfx::setViewFrameBuffer(index, m_framebuffer->target()); - } - bgfx::setViewSeq(index, true); - bgfx::setViewRect(index, 0, 0, m_width[index], m_height[index]); + bgfx::setViewFrameBuffer(view_index, m_framebuffer->target()); + } + + bgfx::setViewSeq(view_index, true); + bgfx::setViewRect(view_index, 0, 0, m_width[window_index], m_height[window_index]); // Setup view transform. - { - float view[16]; - bx::mtxIdentity(view); - - float left = 0.0f; - float top = 0.0f; - float right = m_width[index]; - float bottom = m_height[index]; - float proj[16]; - bx::mtxOrtho(proj, left, right, bottom, top, 0.0f, 100.0f); - bgfx::setViewTransform(index, view, proj); - } - bgfx::setViewClear(index + float proj[16]; + bx::mtxOrtho(proj, 0.0f, m_width[window_index], m_height[window_index], 0.0f, 0.0f, 100.0f); + bgfx::setViewTransform(view_index, nullptr, proj); + + bgfx::setViewClear(view_index , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH , 0x000000ff , 1.0f @@ -824,6 +897,7 @@ int renderer_bgfx::draw(int update) bool atlas_valid = update_atlas(); render_primitive *prim = window().m_primlist->first(); + std::vector<screen_device*> screens; while (prim != nullptr) { UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags); @@ -831,13 +905,29 @@ int renderer_bgfx::draw(int update) bgfx::TransientVertexBuffer buffer; allocate_buffer(prim, blend, &buffer); - buffer_status status = buffer_primitives(index, atlas_valid, &prim, &buffer); - - if (status != BUFFER_EMPTY) + int32_t screen = 0; + if (PRIMFLAG_GET_SCREENTEX(prim->flags)) + { + for (screen = 0; screen < screens.size(); screen++) + { + if (screens[screen] == prim->container->screen()) + { + break; + } + } + if (screen == screens.size()) + { + screens.push_back(prim->container->screen()); + } + } + + buffer_status status = buffer_primitives(view_index, atlas_valid, &prim, &buffer, screen); + + if (status != BUFFER_EMPTY && status != BUFFER_SCREEN) { bgfx::setVertexBuffer(&buffer); - bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->handle()); - m_gui_effect[blend]->submit(index); + bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->texture()); + m_gui_effect[blend]->submit(view_index); } if (status != BUFFER_DONE && status != BUFFER_PRE_FLUSH) @@ -850,16 +940,21 @@ int renderer_bgfx::draw(int update) // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. - bgfx::touch(index); + bgfx::touch(view_index); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. - if (index==0) bgfx::frame(); + if (window_index == 0) + { + bgfx::frame(); + } + + s_current_view++; return 0; } -renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer) +renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen) { int vertices = 0; @@ -893,8 +988,17 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atl { return BUFFER_PRE_FLUSH; } - render_textured_quad(view, *prim, buffer); - return BUFFER_EMPTY; + + if (PRIMFLAG_GET_SCREENTEX((*prim)->flags) && m_screen_chains.size() > window().m_index && m_screen_chains[window().m_index].size() > 0) + { + render_post_screen_quad(view, *prim, buffer, screen); + return BUFFER_SCREEN; + } + else + { + render_textured_quad(view, *prim, buffer); + return BUFFER_EMPTY; + } } } break; @@ -923,25 +1027,26 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atl return BUFFER_FLUSH; } -void renderer_bgfx::set_bgfx_state(UINT32 blend) +uint64_t renderer_bgfx::get_blend_state(UINT32 blend) { - uint64_t flags = BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_DEPTH_TEST_ALWAYS; - switch (blend) { - case BLENDMODE_NONE: - bgfx::setState(flags); - break; case BLENDMODE_ALPHA: - bgfx::setState(flags | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)); - break; + return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); case BLENDMODE_RGB_MULTIPLY: - bgfx::setState(flags | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO)); - break; + return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_DST_COLOR, BGFX_STATE_BLEND_ZERO); case BLENDMODE_ADD: - bgfx::setState(flags | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_ONE)); - break; + return BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_ONE); + default: + return 0L; } + return 0L; +} + +void renderer_bgfx::set_bgfx_state(UINT32 blend) +{ + uint64_t flags = BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_DEPTH_TEST_ALWAYS; + bgfx::setState(flags | get_blend_state(blend)); } bool renderer_bgfx::update_atlas() @@ -985,7 +1090,7 @@ void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer } m_hash_to_entry[rect.hash()] = rect; const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(rect.format(), rect.width(), rect.height(), rect.rowpixels(), rect.palette(), rect.base()); - bgfx::updateTexture2D(m_texture_cache->handle(), 0, rect.x(), rect.y(), rect.width(), rect.height(), mem); + bgfx::updateTexture2D(m_texture_cache->texture(), 0, rect.x(), rect.y(), rect.width(), rect.height(), mem); } } } @@ -1053,7 +1158,6 @@ bool renderer_bgfx::check_for_dirty_atlas() void renderer_bgfx::allocate_buffer(render_primitive *prim, UINT32 blend, bgfx::TransientVertexBuffer *buffer) { int vertices = 0; - bool mode_switched = false; while (prim != nullptr && !mode_switched) { @@ -1072,11 +1176,11 @@ void renderer_bgfx::allocate_buffer(render_primitive *prim, UINT32 blend, bgfx:: } else { - mode_switched = true; if (vertices == 0) { vertices += 6; } + mode_switched = true; } } else @@ -1105,5 +1209,36 @@ void renderer_bgfx::allocate_buffer(render_primitive *prim, UINT32 blend, bgfx:: slider_state* renderer_bgfx::get_slider_list() { - return nullptr; + if (m_screen_chains.size() <= window().m_index || m_screen_chains[window().m_index].size() == 0) + { + return nullptr; + } + + slider_state *listhead = nullptr; + slider_state **tailptr = &listhead; + for (std::vector<bgfx_chain*> screen : m_screen_chains) + { + for (bgfx_chain* chain : screen) + { + std::vector<bgfx_slider*> sliders = chain->sliders(); + for (bgfx_slider* slider : sliders) + { + if (*tailptr == nullptr) + { + *tailptr = slider->core_slider(); + } + else + { + (*tailptr)->next = slider->core_slider(); + tailptr = &(*tailptr)->next; + } + } + } + } + if (*tailptr != nullptr) + { + (*tailptr)->next = nullptr; + } + m_sliders_dirty = false; + return listhead; } |