trunk/src/osd/windows/d3dhlsl.c
r19929 | r19930 | |
193 | 193 | master_enable = false; |
194 | 194 | prescale_size_x = 1; |
195 | 195 | prescale_size_y = 1; |
196 | | prescale_force_x = 0; |
197 | | prescale_force_y = 0; |
| 196 | prescale_force_x = 1; |
| 197 | prescale_force_y = 1; |
198 | 198 | preset = -1; |
199 | 199 | shadow_texture = NULL; |
200 | 200 | options = NULL; |
r19929 | r19930 | |
571 | 571 | |
572 | 572 | |
573 | 573 | //============================================================ |
574 | | // remove_render_target - remove an active cache target when |
| 574 | // remove_cache_target - remove an active cache target when |
575 | 575 | // refcount hits zero |
576 | 576 | //============================================================ |
577 | 577 | |
r19929 | r19930 | |
581 | 581 | { |
582 | 582 | if (cache == cachehead) |
583 | 583 | { |
584 | | cachehead= cachehead->next; |
| 584 | cachehead = cachehead->next; |
585 | 585 | } |
586 | 586 | |
587 | 587 | if (cache->prev != NULL) |
r19929 | r19930 | |
605 | 605 | |
606 | 606 | void hlsl_info::remove_render_target(d3d_texture_info *texture) |
607 | 607 | { |
608 | | d3d_render_target *rt = find_render_target(texture); |
| 608 | remove_render_target(find_render_target(texture)); |
| 609 | } |
609 | 610 | |
| 611 | void hlsl_info::remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) |
| 612 | { |
| 613 | d3d_render_target *target = find_render_target(width, height, screen_index, page_index); |
| 614 | if (target != NULL) |
| 615 | { |
| 616 | remove_render_target(target); |
| 617 | } |
| 618 | } |
| 619 | |
| 620 | void hlsl_info::remove_render_target(d3d_render_target *rt) |
| 621 | { |
610 | 622 | if (rt != NULL) |
611 | 623 | { |
612 | 624 | if (rt == targethead) |
r19929 | r19930 | |
624 | 636 | rt->next->prev = rt->prev; |
625 | 637 | } |
626 | 638 | |
627 | | d3d_cache_target *cache = find_cache_target(rt->screen_index); |
| 639 | d3d_cache_target *cache = find_cache_target(rt->screen_index, rt->width, rt->height); |
628 | 640 | if (cache != NULL) |
629 | 641 | { |
630 | | cache->ref_count--; |
631 | | if (cache->ref_count == 0) |
632 | | { |
633 | | remove_cache_target(cache); |
634 | | } |
| 642 | remove_cache_target(cache); |
635 | 643 | } |
| 644 | |
| 645 | int screen_index = rt->screen_index; |
| 646 | int other_page = 1 - rt->page_index; |
| 647 | int width = rt->width; |
| 648 | int height = rt->height; |
| 649 | |
636 | 650 | global_free(rt); |
| 651 | |
| 652 | // Remove other double-buffered page (if it exists) |
| 653 | remove_render_target(width, height, screen_index, other_page); |
637 | 654 | } |
638 | 655 | } |
639 | 656 | |
r19929 | r19930 | |
986 | 1003 | shadow_texture = texture_create(d3d, &texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32)); |
987 | 1004 | } |
988 | 1005 | |
| 1006 | prescale_force_x = 1; |
| 1007 | prescale_force_y = 1; |
| 1008 | |
989 | 1009 | if(!read_ini) |
990 | 1010 | { |
991 | 1011 | prescale_force_x = winoptions.d3d_hlsl_prescale_x(); |
r19929 | r19930 | |
1038 | 1058 | options->yiq_scan_time = winoptions.screen_yiq_scan_time(); |
1039 | 1059 | options->yiq_phase_count = winoptions.screen_yiq_phase_count(); |
1040 | 1060 | } |
| 1061 | if (!prescale_force_x) |
| 1062 | { |
| 1063 | prescale_force_x = 1; |
| 1064 | } |
| 1065 | if (!prescale_force_y) |
| 1066 | { |
| 1067 | prescale_force_y = 1; |
| 1068 | } |
1041 | 1069 | g_slider_list = init_slider_list(); |
1042 | 1070 | |
1043 | 1071 | const char *fx_dir = downcast<windows_options &>(window->machine().options()).screen_post_fx_dir(); |
r19929 | r19930 | |
1287 | 1315 | { |
1288 | 1316 | d3d_render_target *curr = targethead; |
1289 | 1317 | |
1290 | | while (curr != NULL && curr->info != info) |
| 1318 | UINT32 screen_index_data = (UINT32)info->texinfo.osddata; |
| 1319 | UINT32 screen_index = screen_index_data >> 1; |
| 1320 | UINT32 page_index = screen_index_data & 1; |
| 1321 | |
| 1322 | while (curr != NULL && (curr->screen_index != screen_index || curr->page_index != page_index || curr->width != info->texinfo.width || curr->height != info->texinfo.height)) |
1291 | 1323 | { |
1292 | 1324 | curr = curr->next; |
1293 | 1325 | } |
r19929 | r19930 | |
1297 | 1329 | |
1298 | 1330 | |
1299 | 1331 | //============================================================ |
| 1332 | // hlsl_info::find_render_target |
| 1333 | //============================================================ |
| 1334 | |
| 1335 | d3d_render_target* hlsl_info::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) |
| 1336 | { |
| 1337 | d3d_render_target *curr = targethead; |
| 1338 | |
| 1339 | while (curr != NULL && (curr->width != width || curr->height != height || curr->screen_index != screen_index || curr->page_index != page_index)) |
| 1340 | { |
| 1341 | curr = curr->next; |
| 1342 | } |
| 1343 | |
| 1344 | return curr; |
| 1345 | } |
| 1346 | |
| 1347 | |
| 1348 | //============================================================ |
1300 | 1349 | // hlsl_info::find_cache_target |
1301 | 1350 | //============================================================ |
1302 | 1351 | |
1303 | | d3d_cache_target* hlsl_info::find_cache_target(int screen_index) |
| 1352 | d3d_cache_target* hlsl_info::find_cache_target(UINT32 screen_index, int width, int height) |
1304 | 1353 | { |
1305 | 1354 | d3d_cache_target *curr = cachehead; |
1306 | 1355 | |
1307 | | while (curr != NULL && curr->screen_index != screen_index) |
| 1356 | while (curr != NULL && (curr->screen_index != screen_index || curr->width != width || curr->height != height)) |
1308 | 1357 | { |
1309 | 1358 | curr = curr->next; |
1310 | 1359 | } |
r19929 | r19930 | |
1332 | 1381 | { |
1333 | 1382 | return; |
1334 | 1383 | } |
1335 | | d3d_cache_target *ct = find_cache_target(rt->screen_index); |
| 1384 | d3d_cache_target *ct = find_cache_target(rt->screen_index, poly->texture->texinfo.width, poly->texture->texinfo.height); |
1336 | 1385 | |
1337 | 1386 | if(options->yiq_enable) |
1338 | 1387 | { |
r19929 | r19930 | |
1782 | 1831 | |
1783 | 1832 | |
1784 | 1833 | //============================================================ |
1785 | | // hlsl_info::register_texture |
| 1834 | // hlsl_info::register_prescaled_texture |
1786 | 1835 | //============================================================ |
1787 | 1836 | |
1788 | | int hlsl_info::register_prescaled_texture(d3d_texture_info *texture, int scwidth, int scheight) |
| 1837 | bool hlsl_info::register_prescaled_texture(d3d_texture_info *texture) |
1789 | 1838 | { |
1790 | | if (!master_enable || !d3dintf->post_fx_available) |
1791 | | return 0; |
1792 | | |
1793 | | d3d_info *d3d = (d3d_info *)window->drawdata; |
1794 | | |
1795 | | // Find the nearest prescale factor that is over our screen size |
1796 | | int hlsl_prescale_x = prescale_force_x ? prescale_force_x : 1; |
1797 | | if(!prescale_force_x) |
1798 | | { |
1799 | | while(scwidth * hlsl_prescale_x < d3d->width) hlsl_prescale_x++; |
1800 | | prescale_size_x = hlsl_prescale_x; |
1801 | | } |
1802 | | |
1803 | | int hlsl_prescale_y = prescale_force_y ? prescale_force_y : 1; |
1804 | | if(!prescale_force_y) |
1805 | | { |
1806 | | while(scheight * hlsl_prescale_y < d3d->height) hlsl_prescale_y++; |
1807 | | prescale_size_y = hlsl_prescale_y; |
1808 | | } |
1809 | | |
1810 | | if (!add_render_target(d3d, texture, scwidth, scheight, hlsl_prescale_x, hlsl_prescale_y)) |
1811 | | return 1; |
1812 | | |
1813 | | options->params_dirty = true; |
1814 | | |
1815 | | enumerate_screens(); |
1816 | | |
1817 | | return 0; |
| 1839 | return register_texture(texture, texture->rawwidth, texture->rawheight, texture->xprescale, texture->yprescale); |
1818 | 1840 | } |
1819 | 1841 | |
1820 | 1842 | |
1821 | 1843 | //============================================================ |
1822 | 1844 | // hlsl_info::add_cache_target - register a cache target |
1823 | 1845 | //============================================================ |
1824 | | bool hlsl_info::add_cache_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y, int screen_index) |
| 1846 | bool hlsl_info::add_cache_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index) |
1825 | 1847 | { |
1826 | 1848 | d3d_cache_target* target = (d3d_cache_target*)global_alloc_clear(d3d_cache_target); |
1827 | 1849 | |
1828 | | if (!target->init(d3d, d3dintf, width, height, prescale_x, prescale_y)) |
| 1850 | if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale)) |
1829 | 1851 | { |
1830 | 1852 | global_free(target); |
1831 | 1853 | return false; |
1832 | 1854 | } |
1833 | 1855 | |
| 1856 | target->width = info->texinfo.width; |
| 1857 | target->height = info->texinfo.height; |
| 1858 | |
1834 | 1859 | target->next = cachehead; |
1835 | 1860 | target->prev = NULL; |
1836 | 1861 | |
1837 | 1862 | target->screen_index = screen_index; |
1838 | | target->ref_count = 1; |
1839 | 1863 | |
1840 | 1864 | if (cachehead != NULL) |
1841 | 1865 | { |
r19929 | r19930 | |
1850 | 1874 | // hlsl_info::add_render_target - register a render target |
1851 | 1875 | //============================================================ |
1852 | 1876 | |
1853 | | bool hlsl_info::add_render_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y) |
| 1877 | bool hlsl_info::add_render_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int xprescale, int yprescale) |
1854 | 1878 | { |
| 1879 | if (find_render_target(info)) |
| 1880 | { |
| 1881 | remove_render_target(info); |
| 1882 | } |
| 1883 | |
| 1884 | UINT32 screen_index_data = (UINT32)info->texinfo.osddata; |
| 1885 | UINT32 screen_index = screen_index_data >> 1; |
| 1886 | UINT32 page_index = screen_index_data & 1; |
| 1887 | |
1855 | 1888 | d3d_render_target* target = (d3d_render_target*)global_alloc_clear(d3d_render_target); |
1856 | 1889 | |
1857 | | if (!target->init(d3d, d3dintf, width, height, prescale_x, prescale_y)) |
| 1890 | if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale)) |
1858 | 1891 | { |
1859 | 1892 | global_free(target); |
1860 | 1893 | return false; |
r19929 | r19930 | |
1862 | 1895 | |
1863 | 1896 | target->info = info; |
1864 | 1897 | |
1865 | | UINT32 screen_index_data = (UINT32)info->texinfo.osddata; |
1866 | | target->screen_index = screen_index_data >> 1; |
1867 | | target->page_index = screen_index_data & 1; |
| 1898 | target->width = info->texinfo.width; |
| 1899 | target->height = info->texinfo.height; |
1868 | 1900 | |
1869 | | d3d_cache_target* cache = find_cache_target(target->screen_index); |
| 1901 | target->screen_index = screen_index; |
| 1902 | target->page_index = page_index; |
| 1903 | |
| 1904 | d3d_cache_target* cache = find_cache_target(target->screen_index, info->texinfo.width, info->texinfo.height); |
1870 | 1905 | if (cache == NULL) |
1871 | 1906 | { |
1872 | | if (!add_cache_target(d3d, info, width, height, prescale_x, prescale_y, target->screen_index)) |
| 1907 | if (!add_cache_target(d3d, info, width, height, xprescale * prescale_force_x, yprescale * prescale_force_y, target->screen_index)) |
1873 | 1908 | { |
1874 | 1909 | global_free(target); |
1875 | 1910 | return false; |
1876 | 1911 | } |
1877 | 1912 | } |
1878 | | else |
1879 | | { |
1880 | | cache->ref_count++; |
1881 | | } |
1882 | 1913 | |
1883 | 1914 | target->next = targethead; |
1884 | 1915 | target->prev = NULL; |
r19929 | r19930 | |
1901 | 1932 | num_screens = iter.count(); |
1902 | 1933 | } |
1903 | 1934 | |
| 1935 | |
1904 | 1936 | //============================================================ |
1905 | 1937 | // hlsl_info::register_texture |
1906 | 1938 | //============================================================ |
1907 | 1939 | |
1908 | | int hlsl_info::register_texture(d3d_texture_info *texture) |
| 1940 | bool hlsl_info::register_texture(d3d_texture_info *texture) |
1909 | 1941 | { |
1910 | | enumerate_screens(); |
| 1942 | return register_texture(texture, texture->rawwidth, texture->rawheight, 1, 1); |
| 1943 | } |
1911 | 1944 | |
| 1945 | |
| 1946 | //============================================================ |
| 1947 | // hlsl_info::register_texture(d3d_texture_info, int, int, int, int) |
| 1948 | //============================================================ |
| 1949 | |
| 1950 | bool hlsl_info::register_texture(d3d_texture_info *texture, int width, int height, int xscale, int yscale) |
| 1951 | { |
1912 | 1952 | if (!master_enable || !d3dintf->post_fx_available) |
1913 | 1953 | return 0; |
1914 | 1954 | |
| 1955 | enumerate_screens(); |
| 1956 | |
1915 | 1957 | d3d_info *d3d = (d3d_info *)window->drawdata; |
1916 | 1958 | |
1917 | 1959 | // Find the nearest prescale factor that is over our screen size |
1918 | | int hlsl_prescale_x = prescale_force_x ? prescale_force_x : 1; |
1919 | | if(!prescale_force_x) |
1920 | | { |
1921 | | while(texture->rawwidth * hlsl_prescale_x < d3d->width) hlsl_prescale_x++; |
1922 | | prescale_size_x = hlsl_prescale_x; |
1923 | | } |
| 1960 | int hlsl_prescale_x = prescale_force_x; |
| 1961 | int hlsl_prescale_y = prescale_force_y; |
1924 | 1962 | |
1925 | | int hlsl_prescale_y = prescale_force_y ? prescale_force_y : 1; |
1926 | | if(!prescale_force_y) |
1927 | | { |
1928 | | while(texture->rawheight * hlsl_prescale_y < d3d->height) hlsl_prescale_y++; |
1929 | | prescale_size_y = hlsl_prescale_y; |
1930 | | } |
| 1963 | if (!add_render_target(d3d, texture, width, height, xscale * hlsl_prescale_x, yscale * hlsl_prescale_y)) |
| 1964 | return false; |
1931 | 1965 | |
1932 | | if (!add_render_target(d3d, texture, texture->rawwidth, texture->rawheight, hlsl_prescale_x, hlsl_prescale_y)) |
1933 | | return 1; |
1934 | | |
1935 | 1966 | options->params_dirty = true; |
1936 | 1967 | |
1937 | | return 0; |
| 1968 | return true; |
1938 | 1969 | } |
1939 | 1970 | |
1940 | 1971 | //============================================================ |
trunk/src/osd/windows/d3dhlsl.h
r19929 | r19930 | |
116 | 116 | void render_quad(d3d_poly_info *poly, int vertnum); |
117 | 117 | void end(); |
118 | 118 | |
119 | | int register_texture(d3d_texture_info *texture); |
120 | | int register_prescaled_texture(d3d_texture_info *texture, int scwidth, int scheight); |
121 | | bool add_render_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y); |
122 | | bool add_cache_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y, int screen_index); |
| 119 | bool register_texture(d3d_texture_info *texture); |
| 120 | bool register_prescaled_texture(d3d_texture_info *texture); |
| 121 | bool add_render_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int xprescale, int yprescale); |
| 122 | bool add_cache_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index); |
123 | 123 | |
124 | 124 | void window_save(); |
125 | 125 | void window_record(); |
r19929 | r19930 | |
131 | 131 | |
132 | 132 | void frame_complete(); |
133 | 133 | |
134 | | void set_texture(d3d_texture_info *texture); |
135 | | void remove_render_target(d3d_texture_info *texture); |
| 134 | void set_texture(d3d_texture_info *texture); |
| 135 | d3d_render_target * find_render_target(d3d_texture_info *info); |
| 136 | void remove_render_target(d3d_texture_info *texture); |
| 137 | void remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index); |
| 138 | void remove_render_target(d3d_render_target *rt); |
136 | 139 | |
137 | 140 | int create_resources(); |
138 | 141 | void delete_resources(); |
r19929 | r19930 | |
146 | 149 | void end_avi_recording(); |
147 | 150 | void begin_avi_recording(const char *name); |
148 | 151 | |
149 | | d3d_render_target * find_render_target(d3d_texture_info *info); |
150 | | d3d_cache_target * find_cache_target(int screen_index); |
| 152 | bool register_texture(d3d_texture_info *texture, int width, int height, int xscale, int yscale); |
| 153 | |
| 154 | d3d_render_target* find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index); |
| 155 | d3d_cache_target * find_cache_target(UINT32 screen_index, int width, int height); |
151 | 156 | void remove_cache_target(d3d_cache_target *cache); |
152 | 157 | |
153 | 158 | d3d_base * d3dintf; // D3D interface |
trunk/src/osd/windows/drawd3d.c
r19929 | r19930 | |
1801 | 1801 | texture->d3dfinaltex = texture->d3dtex; |
1802 | 1802 | texture->type = d3d->dynamic_supported ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN; |
1803 | 1803 | |
1804 | | int ret = d3d->hlsl->register_texture(texture); |
1805 | | if (ret != 0) |
| 1804 | if (d3d->hlsl->enabled() && !d3d->hlsl->register_texture(texture)) |
1806 | 1805 | goto error; |
1807 | 1806 | |
1808 | 1807 | break; |
r19929 | r19930 | |
1843 | 1842 | result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &texture->d3dfinaltex); |
1844 | 1843 | if (result == D3D_OK) |
1845 | 1844 | { |
1846 | | int ret = d3d->hlsl->register_prescaled_texture(texture, scwidth, scheight); |
1847 | | if (ret != 0) |
| 1845 | if (d3d->hlsl->enabled() && !d3d->hlsl->register_prescaled_texture(texture)) |
| 1846 | { |
1848 | 1847 | goto error; |
1849 | | |
| 1848 | } |
1850 | 1849 | break; |
1851 | 1850 | } |
1852 | 1851 | (*d3dintf->texture.release)(texture->d3dtex); |
r19929 | r19930 | |
2522 | 2521 | // find a match |
2523 | 2522 | for (texture = d3d->texlist; texture != NULL; texture = texture->next) |
2524 | 2523 | { |
| 2524 | UINT32 test_screen = (UINT32)texture->texinfo.osddata >> 1; |
| 2525 | UINT32 test_page = (UINT32)texture->texinfo.osddata & 1; |
| 2526 | UINT32 prim_screen = (UINT32)prim->texture.osddata >> 1; |
| 2527 | UINT32 prim_page = (UINT32)prim->texture.osddata & 1; |
| 2528 | if (test_screen != prim_screen || test_page != prim_page) |
| 2529 | { |
| 2530 | continue; |
| 2531 | } |
| 2532 | |
2525 | 2533 | if (texture->hash == texhash && |
2526 | 2534 | texture->texinfo.base == prim->texture.base && |
2527 | 2535 | texture->texinfo.width == prim->texture.width && |
2528 | 2536 | texture->texinfo.height == prim->texture.height && |
2529 | 2537 | ((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0) |
2530 | 2538 | { |
2531 | | return texture; |
| 2539 | // Reject a texture if it belongs to an out-of-date render target, so as to cause the HLSL system to re-cache |
| 2540 | if (d3d->hlsl->enabled() && prim->texture.width != 0 && prim->texture.height != 0 && (prim->flags & PRIMFLAG_SCREENTEX_MASK) != 0) |
| 2541 | { |
| 2542 | if (d3d->hlsl->find_render_target(texture) != NULL) |
| 2543 | { |
| 2544 | return texture; |
| 2545 | } |
| 2546 | } |
| 2547 | else |
| 2548 | { |
| 2549 | return texture; |
| 2550 | } |
2532 | 2551 | } |
2533 | 2552 | } |
2534 | 2553 | |
2535 | 2554 | // nothing found, check if we need to unregister something with hlsl |
2536 | | if (d3d->hlsl != NULL) |
| 2555 | if (d3d->hlsl->enabled()) |
2537 | 2556 | { |
| 2557 | if (prim->texture.width == 0 || prim->texture.height == 0) |
| 2558 | { |
| 2559 | return NULL; |
| 2560 | } |
| 2561 | |
| 2562 | UINT32 prim_screen = (UINT32)prim->texture.osddata >> 1; |
| 2563 | UINT32 prim_page = (UINT32)prim->texture.osddata & 1; |
| 2564 | |
2538 | 2565 | for (texture = d3d->texlist; texture != NULL; texture = texture->next) |
2539 | 2566 | { |
| 2567 | UINT32 test_screen = (UINT32)texture->texinfo.osddata >> 1; |
| 2568 | UINT32 test_page = (UINT32)texture->texinfo.osddata & 1; |
| 2569 | if (test_screen != prim_screen || test_page != prim_page) |
| 2570 | { |
| 2571 | continue; |
| 2572 | } |
| 2573 | |
2540 | 2574 | // Clear our old texture reference |
2541 | 2575 | if (texture->hash == texhash && |
2542 | 2576 | texture->texinfo.base == prim->texture.base && |