Commit 64949e7
committed
gfx/d3d9cg: Recover from shader compile failures instead of black-
screening
Three closely-related issues stacked on top of each other made any
single-pass-or-later compile failure inside a multi-pass preset
permanently brick the driver until restart:
1. d3d9_cg_renderchain_add_pass discarded d3d9_cg_load_program's
return value. When a pass like mdapt-pass3.cg failed to compile
(C5109 domain-conflict, etc.), the pass was still appended to the
chain with vprg/fprg = NULL. The render path then called
cgD3D9BindProgram(NULL) every frame, which leaves the device in
an unspecified state -- on the user's GPU, that's a black core
frame with menu/widgets/overlay still drawing fine (those use
fixed-function or stock-blend, not the renderchain).
2. d3d9_cg_load_program's error: label leaked the partially-created
Cg program(s). In the cgD3D9LoadProgram failure case, pass->fprg
was a valid Cg program object (compile succeeded, GPU-load did
not), and any subsequent code path that didn't NULL-check would
happily try to bind it. Worse, the leaked program objects pin
the surrounding context until cgDestroyContext runs.
3. d3d9_cg_set_shader's failure handling left d3d->renderchain_data
pointing at a half-built chain (whatever passes succeeded before
the failure, plus the bad pass with NULL programs after #1). The
driver kept rendering through that chain. Even reapplying the
stock shader from the menu wouldn't recover, because the menu's
"Apply Shader" path also goes through set_shader -> process_shader
-> restore, hitting the same broken state if anything along the
way faulted.
Fix all three:
- add_pass now memsets the local pass struct (so the error path has
a well-defined struct to walk), checks load_program's return, and
funnels every failure through a single error: label that releases
the Cg programs, vertex declaration, vertex buffer, texture, and
attrib_map it created before the failure point.
- load_program's error: label cgDestroyProgram()s pass->vprg/fprg
(whichever is non-NULL) and zeroes them, so callers that ignore
the return value still see a clean pass struct.
- set_shader, on process_shader-or-restore failure, frees
d3d->shader_path, runs process_shader again to populate the stock
defaults, and calls restore once more to rebuild the chain
against the stock shader. The original return value (false) is
preserved, so the menu still surfaces the failure to the user --
they just don't get stuck on a black screen anymore.
The init-ordering fix (call process_shader before initialize on
the first init path so init_chain doesn't read a calloc-zeroed
fbo struct) is also included, since both regressions would have
needed to be tested together anyway.
Tested with snes9x2010 + DKC2 + sequence: stock -> testie-crt
(7-pass, works) -> mdapt+xbr-hybrid+aa (mdapt-pass3 C5109 failure)
-> stock (recovered). Pre-fix the third step stayed black; post-
fix it goes back to plain stock rendering.1 parent 72cb324 commit 64949e7
1 file changed
Lines changed: 88 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2045 | 2045 | | |
2046 | 2046 | | |
2047 | 2047 | | |
| 2048 | + | |
| 2049 | + | |
| 2050 | + | |
| 2051 | + | |
| 2052 | + | |
| 2053 | + | |
| 2054 | + | |
| 2055 | + | |
| 2056 | + | |
| 2057 | + | |
| 2058 | + | |
| 2059 | + | |
| 2060 | + | |
| 2061 | + | |
| 2062 | + | |
| 2063 | + | |
2048 | 2064 | | |
2049 | 2065 | | |
2050 | 2066 | | |
| |||
2697 | 2713 | | |
2698 | 2714 | | |
2699 | 2715 | | |
| 2716 | + | |
| 2717 | + | |
| 2718 | + | |
| 2719 | + | |
| 2720 | + | |
2700 | 2721 | | |
2701 | | - | |
2702 | | - | |
2703 | 2722 | | |
2704 | 2723 | | |
2705 | 2724 | | |
2706 | 2725 | | |
2707 | | - | |
| 2726 | + | |
| 2727 | + | |
| 2728 | + | |
| 2729 | + | |
| 2730 | + | |
| 2731 | + | |
| 2732 | + | |
| 2733 | + | |
2708 | 2734 | | |
2709 | 2735 | | |
2710 | | - | |
| 2736 | + | |
2711 | 2737 | | |
2712 | 2738 | | |
2713 | 2739 | | |
| |||
2717 | 2743 | | |
2718 | 2744 | | |
2719 | 2745 | | |
2720 | | - | |
| 2746 | + | |
2721 | 2747 | | |
2722 | 2748 | | |
2723 | 2749 | | |
| |||
2735 | 2761 | | |
2736 | 2762 | | |
2737 | 2763 | | |
2738 | | - | |
| 2764 | + | |
2739 | 2765 | | |
2740 | 2766 | | |
2741 | 2767 | | |
| |||
2747 | 2773 | | |
2748 | 2774 | | |
2749 | 2775 | | |
| 2776 | + | |
| 2777 | + | |
| 2778 | + | |
| 2779 | + | |
| 2780 | + | |
| 2781 | + | |
| 2782 | + | |
| 2783 | + | |
| 2784 | + | |
| 2785 | + | |
| 2786 | + | |
| 2787 | + | |
| 2788 | + | |
| 2789 | + | |
| 2790 | + | |
| 2791 | + | |
| 2792 | + | |
| 2793 | + | |
| 2794 | + | |
2750 | 2795 | | |
2751 | 2796 | | |
2752 | 2797 | | |
| |||
3793 | 3838 | | |
3794 | 3839 | | |
3795 | 3840 | | |
3796 | | - | |
| 3841 | + | |
| 3842 | + | |
| 3843 | + | |
| 3844 | + | |
| 3845 | + | |
| 3846 | + | |
| 3847 | + | |
| 3848 | + | |
| 3849 | + | |
| 3850 | + | |
| 3851 | + | |
| 3852 | + | |
| 3853 | + | |
| 3854 | + | |
| 3855 | + | |
| 3856 | + | |
| 3857 | + | |
| 3858 | + | |
| 3859 | + | |
3797 | 3860 | | |
3798 | 3861 | | |
3799 | 3862 | | |
| |||
3884 | 3947 | | |
3885 | 3948 | | |
3886 | 3949 | | |
| 3950 | + | |
| 3951 | + | |
| 3952 | + | |
| 3953 | + | |
| 3954 | + | |
| 3955 | + | |
| 3956 | + | |
| 3957 | + | |
| 3958 | + | |
| 3959 | + | |
| 3960 | + | |
| 3961 | + | |
| 3962 | + | |
| 3963 | + | |
| 3964 | + | |
| 3965 | + | |
| 3966 | + | |
| 3967 | + | |
3887 | 3968 | | |
3888 | 3969 | | |
3889 | 3970 | | |
| |||
0 commit comments