The code is building fine but at startup the rendere library cannot by
loaded: "LoadLibrary returned 126" Disable thread local as a band-aid
fix, it might be worth to have a deeper look and figure out what exactly
goes wrong.
Closes#762.
This is a corner case, next to unlikely that anyone would have ever hit
it. That's why my tests with asan didn't find the leak. The if case are
paletted textures which must be enabled by setting `gl1_palettedtexture`
to 1 and requires an GPU with support for `GL_EXT_paletted_texture`.
Nvidia dropped support for that in 2005. Additionally a sky texture
must be uploaded.
This was an issue an Windows with it's small stack. It didn't trigger on
Linux. While at it make the code a little bit more robust by allocating
exactly the amount of data we need and not some arbitrary guess.
Setting r_2D_unfiltered to 1 (0 is default), 2D elements (GUI, menu,
console) are rendered without texture filtering in GL1 and GL3, while
everything else is still rendered with whatever is set in gl_texturemode
This setting (and now also gl_nolerp_list) is applied immediately,
so no vid_restart is needed.
refs #752
While having a Vulkan renderer in Yamagi Quake II sounded like a good
idea, especially for cheap hardware with broken OpenGL drivers, the last
weeks showed that the code is not ready for primetime. Some examples
for critical problems:
* Render glitches when using non-standard assets. Everything with more
polygons and texture resultion than baseq2 seems to be broken.
* The startup and shutdown code is a mess. While I fixes the most
critical bug, there're a lot of cases left. Startup and shutdown
mostly works by luck.
* At least one memory leak in the model code.
And neither @DanielGibson nor myself have deeper knowledge about Vulkan.
We don't have the time and the motivation to learn it. While some
community members did excellent work on ref_vk (especially @0lvin and
@rg3), the community maintenance promised in the initial pull request
never really materialized. Therefor we risk ending up with a renderer
that we can't and won't maintain by ourself.
Vulkan is not gone. The code will be recommitted in a separate
repository at: https://github.com/yquake2/ref_vk
We're willing to give community members commit access to that
repository. Send a substantial pull request and ask for it.
So far I haven't seen a restart loop, but at least in theory they'e
possible. Because its hard to break out of such loop, especially on
Windows were interaction with the taskmanager is required, play save
and restart max. 3 times in a row.
The timeout specifies how long Vulkan waits for the next frame becoming
available. On the one hand we need to take the vsync or the possibility
that we get scheduled away for longer times into account. On the other
hand we don't want to wait for too long, the game may run into the
timeout after its windows was minimized, etc. 500 milliseconds sounds
like a good compromise.
Some GPU drivers set a maximal extent size of 0x0 when the window gets
minimized. One example is Intel on Windows. A swapchain with extent
size of 0x0 is invalid, so we cannot reinitialize the renderer... Work
around that by postponing the restart as long as the maxmimal extent
size stays 0x0.
This could should be done in the client (don't call into th renderer
when the window is minimized), but it would need a lot of changes
to the client <-> renderer interactions. So take the easy route.
The client might call into the renderer after it was shut down by
`VID_ShutdownRenderer()` or initialized `VID_LoadRenderer()`. This
is arguably a client bug, but hard to fix on client side and not
a problem for all other renderers. Work around it by marking the
current frame as 'not started' at Vulkan shutdown and init.
This is more in line with the rest of the code. Reinitializing the
internal state when building a new context is saver than relying on
Vulkan telling us that something is wrong an reacting to that.
Just calling `QVk_Shutdown()` is wrong. It doesn't wait for Vulkan to
finish, which can cause crashes. And it leaks some ressources which
makes the GPU driver unhappy.
The ref_vk renderer was written for vkQ2 which has differend renderer
<-> client semantics. In YQ2 we can end up initializing or shutting the
renderer down several times. Not by the client, but by the client not
knowing of the renderer has already initialized / shutdown it's internal
state. This is fatal, leading to ressource leaks, crashes and other fun.
Introduce a new global variable `vk_initialize` and use it to track if
we're initialized or not.
Since `vid_fullscreen` isn't special anymore, it's completely handled by
`Vid_Restart_f()`, which in turn simplifies the spaghetti code in the vk
renderer. If I understand that glibberish correctly the only we need to
handle is the partial restart in `QVk_Restart()`.
VK_WARNING: Validation Performance Warning: [ UNASSIGNED-BestPractices-vkCreateRenderPass-image-requires-memory ] Object 0: handle = 0x58e7d23ea0, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x4003982 | Attachment 2 in the VkRenderPass is a multisampled image with 4 samples, but it uses loadOp/storeOp which requires accessing data from memory. Multisampled images should always be loadOp = CLEAR or DONT_CARE, storeOp = DONT_CARE. This allows the implementation to use lazily allocated memory effectively. (performance)
This brings yquake2 closer to vkQuake2 regarding renderer restarts when
the swapchain is out of date, among other situations that trigger a
Vulkan renderer restart.
Basically, the current behavior has the problem that when the renderer
is restarted at the beginning of the frame, the models are lost and we
end up with "ERROR: Mod_PointInLeaf: bad model" when attempting to
render anything after that restart.
To solve this, we move the restart logic to EndFrame and add a twist to
it: we use a vid_refresh variable to signal the server that the client
needs re-registration before starting the next frame cleanly, which will
trigger the registration logic to prepare the models again.
When creating the Vulkan texture samplers, make them have the real
anisotropic filtering value selected by the user. This has two side
effects:
* We no longer need two sets of texture samplers in Vulkan (one with and
another one without anisotropic filtering).
* The anisotropic filter value in Vulkan is no longer an on/off switch
and we use the value as chosen by the user.
Switching this back to Vanilla Q2 behavior fixes at least one lightning
problem in the space map in baseq2. It'll break the lighting in some
addon maps, but is more correct from a global standpoint. You can't
have everything...
Closes#677.
If an error is detected in vkAcquireNextImageKHR or vkQueuePresentKHR,
avoid restarting the whole video system and the game window. Instead,
shut down the Vulkan subsystem as gracefully as possible and restart it
without touching the window.
This fixes the problem with infinite video restarts under the Gnome
desktop environment.
When windowed or in "switch resolution" mode, the viewport must be kept
in the top-left corner or it will appear cut while in fullscreen.
Also, make offset and width calculations safe from the point of view of
the swapchain extent, in case there's a mismatch.
Since we are now loading the world color buffer content before drawing
on them again, we need to make sure the attachment layout transition
from shader-read-optimal to color-attachment-optimal happens before
color attachment read operations.
The contents of the previous drawn frame, used to mask geometry glitches
due to geometry sometimes not being watertight, was not being correctly
loaded for MSAA cases.
When MSAA is not used, the single-sample attachment needs to be loaded
and stored. With MSAA enabled, it's the multisample attachment the one
needing to be loaded and stored.
The pipeline used to draw a texture quad was only created compatible
with the RP_UI render pass, which has a single-sample color attachment.
This made the pipeline work when MSAA was disabled, but it did not work
properly with it enabled.
To fix the issue, create a set of pipelines, instead of a single one,
with compatibility with the different types of render passes, as the
pipeline is used for both the scaled down view borders as well as UI
elements in the third render pass.
src/client/refresh/soft/sw_main.c:
1512 (style) Variable 'err' is assigned a value that is never used. [unreadVariable]
src/client/refresh/vk/vk_rmain.c:
1023 (style) Suspicious calculation. Please use parentheses to clarify the code. The code ''a&b?c:d'' should be written as either ''(a&b)?c:d'' or ''a&(b?c:d)''. [clarifyCalculation]
src/client/sound/ogg.c:
335 (style,inconclusive) Function 'OGG_PlayTrack' argument 1 names different: declaration 'track' definition 'trackNo'. [funcArgNamesDifferent]
212 (style) Local variable 'gogTrack' shadows outer variable [shadowVariable]
src/client/sound/sdl.c:
179 (style) The scope of the variable 'i' can be reduced.
180 (style) The scope of the variable 'lpos' can be reduced.
181 (style) The scope of the variable 'ls_paintedtime' can be reduced.
182 (style) The scope of the variable 'out_idx' can be reduced.
183 (style) The scope of the variable 'count' can be reduced.
185 (style) The scope of the variable 'p' can be reduced.
186 (style) The scope of the variable 'snd_linear_count' can be reduced.
187 (style) The scope of the variable 'step' can be reduced.
189 (style) The scope of the variable 'snd_out' can be reduced.
330 (style) The scope of the variable 'data' can be reduced.
368 (style) The scope of the variable 'data' can be reduced.
369 (style) The scope of the variable 'left' can be reduced.
369 (style) The scope of the variable 'right' can be reduced.
401 (style) The scope of the variable 'end' can be reduced.
529 (style) The scope of the variable 's' can be reduced.
799 (style) The scope of the variable 'i' can be reduced.
874 (style) The scope of the variable 'scale' can be reduced.
910 (style) The scope of the variable 'srcsample' can be reduced.
1093 (style) The scope of the variable 'total' can be reduced.
196 (style) Local variable 'i' shadows outer variable [shadowVariable]
197 (style) Local variable 'count' shadows outer variable [shadowVariable]
src/client/sound/sound.c:
450 (style) The scope of the variable 'maleFilename' can be reduced.
980 (style) The scope of the variable 'num' can be reduced.
1085 (style) The scope of the variable 'sfx' can be reduced.
423 (style,inconclusive) Function 'S_RegisterSound' argument 1 names different: declaration 'sample' definition 'name'. [funcArgNamesDifferent]
909 (style,inconclusive) Function 'S_StartLocalSound' argument 1 names different: declaration 's' definition 'sound'. [funcArgNamesDifferent]
1048 (style,inconclusive) Function 'S_Update' argument 2 names different: declaration 'v_forward' definition 'forward'. [funcArgNamesDifferent]
1048 (style,inconclusive) Function 'S_Update' argument 3 names different: declaration 'v_right' definition 'right'. [funcArgNamesDifferent]
1048 (style,inconclusive) Function 'S_Update' argument 4 names different: declaration 'v_up' definition 'up'. [funcArgNamesDifferent]
This commit removes the previous R_CleanupBorders hack and fixes
textured border drawing, so borders are correctly drawn in the right
place and are not taken into account when applying the underwater
effect.
This commit includes the following changes:
* When vid_fullscreen is 1, the game is now drawn centered in the
screen instead of the top left corner, by modifying the viewport and
scissor when drawing the world warp and UI render passes.
* When vid_fullscreen is 1, the world view no longer has an incorrect
size and/or aspect ratio. This was due to the world warp and UI
render passes sampling from the whole color buffer instead of the
restricted render area. To fix this, the postprocessing and world warp
shaders now use unnormalized coordinates, corrected with the frame
offset, and sample directly from the appropriate texels.
* The game no longer outputs pixels which have not been written to,
which are usually displayed black but may come out with undefined
colors. For this, some output color attachments are cleared before
drawing the final elements in the frame.
All renderers had the fix, but it was only optional in the GL renderers.
And there it was missimplemented, cvars must be defined in the renderers
main() function. Otherwise they aren't available at startup.
Rename gl_fixsurfsky to r_fixsurfsky, implement it for all renderers and
enable it by default.
Due to the skybox geometry not always being watertight, it's sometimes
possible to see instances of isolated black pixels flickering along
skybox edges. This happens when the sampling coordinates for the given
pixel fall outside any triangle in the skybox due to the previous
problem.
These pixels are usually visible when MSAA is not used and pixels are
big enough on the screen, like when using lower screen resolutions or
large vk_pixel_size values. If MSAA is used, normally only a few of the
samples fall outside any triangle and the problem is masked a bit, being
harder to spot.
Instead of fixing the skybox clipping routines, which may be
complicated, this commit simply preserves color buffer contents between
frames. If any pixel ends up without coverage, its color will be taken
from a previous draw a few frames before, depending on the swapchain
size. This is usually more than enough to completely mask the problem
visually.
Skybox edges are sometimes visible in Vulkan, specially in lower screen
resolutions or when vk_pixel_size is used to the same effect.
To avoid this problem, draw the skybox using CLAMP_TO_EDGE addressing
mode in samplers. In order to do that, the number of texture samplers is
doubled and a second set of samplers with the new addressing mode are
created, and used only when drawing the skybox.
When calculating the pipeline scissor adjusted for vk_pixel_size, round
scissor offset down and size up. This avoids black bars on image borders
when scaling up if the division is not exact.
This commit adds a new cvar called vk_pixel_size that represents how big
pixels should look in the rendered world in order to simulate lower
screen resolutions. With its default value of 1 everything looks normal,
but with bigger sizes (e.g. 4) the rendered world starts to look
"pixelated" due to pixels appearing bigger.
To implement the effect, the viewport and scissor are modified when
drawing the world so the rendering results cover a smaller area in the
top-left corner of the image.
The post-processing fragment shader is used to scale the image back to
the swapchain size before drawing UI elements on top of it.
The UI is not affected by this change, so the existing UI scaling
options continue to work as before with no changes, adding some
flexibility to the mix.
Related to feature request #588.
src/common/cvar.c:160 Logical disjunction always evaluates to true: c >= '0' || c <= '9'. Are these conditions necessary? Did you intend to use && instead? Are the numbers correct? Are you comparing the correct variables?
src/common/cvar.c:141 The scope of the variable 'c' can be reduced.
src/common/cvar.c:517 The scope of the variable 'c' can be reduced.
src/common/shared/shared.c:1359 Either the condition '!value' is redundant or there is possible null pointer dereference: value.
src/common/shared/shared.c:1371 Either the condition '!value' is redundant or there is possible null pointer dereference: value.
src/common/shared/shared.c:1377 Either the condition '!value' is redundant or there is possible null pointer dereference: value.
src/client/refresh/soft/sw_main.c:1531 Variable 'err' is assigned a value that is never used.
src/client/refresh/gl1/gl1_model.c:39:6: warning: type of ‘LoadSP2’ does not match original declaration [-Wlto-type-mismatch]
src/game/g_turret.c:29:6: warning: type of ‘infantry_die’ does not match original declaration [-Wlto-type-mismatch]
src/game/g_spawn.c:43:6: warning: type of ‘SP_info_player_intermission’ does not match original declaration [-Wlto-type-mismatch]
The QVK shutdown is necessary, otherwise we'll leak all(?) allocated
Vulkan resources in case of a renderer restart by `vid_restart` and the
like. The also fixes some crashes in RADV at renderer shutdown.
vk_common.c:1618:19: style: The if condition is the same as the previous if condition [duplicateCondition]
vk_draw.c:93:7: style: The scope of the variable 'fullname' can be reduced. [variableScope]
vk_draw.c:273:9: style: The scope of the variable 'source' can be reduced. [variableScope]
vk_draw.c:274:8: style: The scope of the variable 'frac' can be reduced. [variableScope]
vk_draw.c:274:14: style: The scope of the variable 'fracstep' can be reduced. [variableScope]
vk_draw.c:276:8: style: The scope of the variable 'row' can be reduced. [variableScope]
vk_draw.c:295:12: style: The scope of the variable 'dest' can be reduced. [variableScope]
vk_draw.c:111:45: style:inconclusive: Function 'Draw_GetPicSize' argument 3 names different: declaration 'name' definition 'pic'. [funcArgNamesDifferent]
vk_draw.c:131:57: style:inconclusive: Function 'Draw_StretchPic' argument 5 names different: declaration 'name' definition 'pic'. [funcArgNamesDifferent]
vk_draw.c:159:53: style:inconclusive: Function 'Draw_PicScaled' argument 4 names different: declaration 'factor' definition 'scale'. [funcArgNamesDifferent]
vk_draw.c:185:56: style:inconclusive: Function 'Draw_TileClear' argument 5 names different: declaration 'name' definition 'pic'. [funcArgNamesDifferent]
vk_image.c:586:7: style: The scope of the variable 'best' can be reduced. [variableScope]
vk_image.c:1170:8: style: The scope of the variable 'p' can be reduced. [variableScope]
vk_image.c:1591:7: style: The scope of the variable 'r' can be reduced. [variableScope]
vk_image.c:1591:10: style: The scope of the variable 'g' can be reduced. [variableScope]
vk_image.c:1591:13: style: The scope of the variable 'b' can be reduced. [variableScope]
vk_image.c:1592:11: style: The scope of the variable 'v' can be reduced. [variableScope]
vk_image.c:1628:9: style: The scope of the variable 'j' can be reduced. [variableScope]
vk_image.c:1261:8: style: Local variable 'i' shadows outer variable [shadowVariable]
vk_light.c:231:18: warning: Identical condition '(back<0)==side', second condition is always false [identicalConditionAfterEarlyExit]
vk_light.c:40:8: style: The scope of the variable 'a' can be reduced. [variableScope]
vk_light.c:306:9: style: The scope of the variable 'add' can be reduced. [variableScope]
vk_mesh.c:107:7: style: The scope of the variable 'count' can be reduced. [variableScope]
vk_mesh.c:316:7: style: The scope of the variable 'count' can be reduced. [variableScope]
vk_mesh.c:317:7: style: The scope of the variable 'i' can be reduced. [variableScope]
vk_mesh.c:647:9: style: The scope of the variable 'min' can be reduced. [variableScope]
vk_mesh.c:766:9: style: Local variable 'model' shadows outer variable [shadowVariable]
vk_mesh.c:267:52: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
vk_mesh.c:750:128: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
vk_model.c:53:9: style: The scope of the variable 'd' can be reduced. [variableScope]
vk_model.c:54:12: style: The scope of the variable 'plane' can be reduced. [variableScope]
vk_model.c:407:7: style: The scope of the variable 'next' can be reduced. [variableScope]
vk_model.c:462:12: style: The scope of the variable 'e' can be reduced. [variableScope]
vk_model.c:519:8: style: The scope of the variable 'planenum' can be reduced. [variableScope]
vk_model.c:519:18: style: The scope of the variable 'side' can be reduced. [variableScope]
vk_model.c:520:8: style: The scope of the variable 'ti' can be reduced. [variableScope]
vk_model.c:613:21: style: The scope of the variable 'p' can be reduced. [variableScope]
vk_model.c:663:21: style: The scope of the variable 'p' can be reduced. [variableScope]
vk_model.c:722:10: style: The scope of the variable 'j' can be reduced. [variableScope]
vk_model.c:783:8: style: The scope of the variable 'bits' can be reduced. [variableScope]
vk_model.c:901:18: style: The scope of the variable 'pinframe' can be reduced. [variableScope]
vk_model.c:901:29: style: The scope of the variable 'poutframe' can be reduced. [variableScope]
vk_model.c:1102:7: style: The scope of the variable 'i' can be reduced. [variableScope]
vk_model.c:1103:13: style: The scope of the variable 'sprout' can be reduced. [variableScope]
vk_model.c:1072:28: style:inconclusive: Function 'R_BeginRegistration' argument 1 names different: declaration 'map' definition 'model'. [funcArgNamesDifferent]
vk_pipeline.c:51:87: style:inconclusive: Function 'QVk_CreatePipeline' argument 2 names different: declaration 'desLayoutCount' definition 'descLayoutCount'. [funcArgNamesDifferent]
vk_rmain.c:405:10: style: The scope of the variable 'scale' can be reduced. [variableScope]
vk_rmain.c:400:28: style:inconclusive: Function 'Vk_DrawParticles' argument 1 names different: declaration 'n' definition 'num_particles'. [funcArgNamesDifferent]
vk_rmain.c:956:62: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
vk_rmain.c:1196:12: style: Variable 'err' is assigned a value that is never used. [unreadVariable]
vk_rmisc.c:97:10: style: The scope of the variable 'temp' can be reduced. [variableScope]
vk_rmisc.c:140:23: style: Variable 'isPreferred' is assigned a value that is never used. [unreadVariable]
vk_rsurf.c:678:11: style: The scope of the variable 'k' can be reduced. [variableScope]
vk_rsurf.c:679:12: style: The scope of the variable 'pplane' can be reduced. [variableScope]
vk_rsurf.c:680:9: style: The scope of the variable 'dot' can be reduced. [variableScope]
vk_rsurf.c:682:12: style: The scope of the variable 'lt' can be reduced. [variableScope]
vk_rsurf.c:741:8: style: The scope of the variable 'i' can be reduced. [variableScope]
vk_rsurf.c:811:22: style: The scope of the variable 'mark' can be reduced. [variableScope]
vk_rsurf.c:980:10: style: The scope of the variable 'c' can be reduced. [variableScope]
vk_rsurf.c:982:7: style: The scope of the variable 'cluster' can be reduced. [variableScope]
vk_rsurf.c:1055:6: style: The scope of the variable 'height' can be reduced. [variableScope]
vk_rsurf.c:1104:13: style: The scope of the variable 'best2' can be reduced. [variableScope]
vk_rsurf.c:1142:11: style: The scope of the variable 'lindex' can be reduced. [variableScope]
vk_rsurf.c:1145:9: style: The scope of the variable 's' can be reduced. [variableScope]
vk_rsurf.c:1145:12: style: The scope of the variable 't' can be reduced. [variableScope]
vk_rsurf.c:1257:12: style: The scope of the variable 'dummy' can be reduced. [variableScope]
vk_swapchain.c:68:7: warning: Possible null pointer dereference: presentModes [nullPointer]
vk_swapchain.c:182:91: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
vk_warp.c:57:8: style: The scope of the variable 'm' can be reduced. [variableScope]
vk_warp.c:64:8: style: The scope of the variable 's' can be reduced. [variableScope]
vk_warp.c:64:11: style: The scope of the variable 't' can be reduced. [variableScope]
vk_warp.c:168:8: style: The scope of the variable 'lindex' can be reduced. [variableScope]
vk_warp.c:325:9: style: The scope of the variable 'j' can be reduced. [variableScope]
vk_warp.c:530:11: style: The scope of the variable 'k' can be reduced. [variableScope]
Menu popup can be called without initial run FrameBegin.
#0 0x0000007ff406bea8 in R_EndWorldRenderpass () at src/client/refresh/vk/vk_rmain.c:937
#1 0x0000007ff4060b5c in Draw_CharScaled (x=12, y=66, num=num@entry=1, scale=1) at src/client/refresh/vk/vk_draw.c:61
#2 0x0000005555581900 in M_DrawCharacter (cx=cx@entry=12, cy=cy@entry=66, num=num@entry=1) at src/client/menu/menu.c:410
#3 0x0000005555581964 in M_DrawTextBox (x=x@entry=12, y=y@entry=66, width=35, lines=3) at src/client/menu/menu.c:487
#4 0x0000005555581fa0 in M_Popup () at src/client/menu/menu.c:580
#5 0x0000005555583ad0 in SearchLocalGames () at src/client/menu/menu.c:2771
#6 0x0000005555583c94 in JoinServer_MenuInit () at src/client/menu/menu.c:2838
#7 0x0000005555585d2c in M_Menu_JoinServer_f () at src/client/menu/menu.c:2863
#8 JoinNetworkServerFunc (unused=<optimized out>) at src/client/menu/menu.c:737
#9 0x0000005555588724 in Action_DoEnter (a=<optimized out>) at src/client/menu/qmenu.c:55
#10 Menu_SelectItem (s=s@entry=0x5555611148 <s_multiplayer_menu>) at src/client/menu/qmenu.c:566
#11 0x0000005555586338 in Default_MenuKey (m=0x5555611148 <s_multiplayer_menu>, key=13) at src/client/menu/menu.c:393
#12 0x00000055555873fc in M_Keydown (key=key@entry=13) at src/client/menu/menu.c:4682
#13 0x000000555556f194 in Key_Event (key=<optimized out>, down=true, special=special@entry=true) at src/client/cl_keyboard.c:1331
#14 0x000000555557f078 in IN_Update () at src/client/input/sdl.c:641
#15 0x0000005555570e64 in CL_Frame (packetdelta=96239, renderdelta=<optimized out>, timedelta=<optimized out>,
packetframe=packetframe@entry=true, renderframe=renderframe@entry=true) at src/client/cl_main.c:802
#16 0x00000055555a8a78 in Qcommon_Frame (usec=96239) at src/common/frame.c:626
#17 0x00000055555a8c98 in Qcommon_Mainloop () at src/common/frame.c:163
#18 0x00000055555a92f0 in Qcommon_Init (argc=1, argv=0x7ffffff358) at src/common/frame.c:377
#19 0x0000005555561e44 in main (argc=1, argv=0x7ffffff358) at src/backends/unix/main.c:123
According to the C standard, arguments to the ctype functions
must fit into unsigned char (presumably so they can be implemented
with simple array access). This causes a build time warning on
NetBSD, and may function incorrectly if any UTF-8 strings are used.
Adaptive vsync is a often requested feauture and easy to implement. Set
`r_vsync` to `2` to enable. This is untested because my system doesn't
support it.
On MacOS texture is cleaned up after render and code have to copy a whole
screen to texture, other platforms save previous texture content and can
be copied only changed parts.
An option like this was often requested since I fixed the gun field of
view in e466554. Since the software renderer is missing the ability to
alter the persepective matrix (e.g. something like glFrustrum()) this
fix fakes the offset by manipulating the guns transformation marix.
That's not perfect, the gun distorts if `sw_gunzposition` is set to
anything but `0`. Values up to `8` are more or less okay. Defaults
to `8` which matches the GL renderer default.
and make sure that after vid_restart (or starting the game) it's used
correctly in GL3.
While at it, made sure that it's *not* applied to textures from
gl_nolerp_list, because they're supposed to always use GL_NEAREST
independent of this setting (used so console font and crosshairs don't
look blurry)
sw_image.c:
203: The potential null pointer is passed into 'memcpy' function. Inspect the first argument. Check lines: 203, 192.
368: The null pointer is passed into 'free' function. Inspect the first argument.
401: Expression '!pic' is always false.
401: There are two 'if' statements with identical conditional expressions. The first 'if' statement contains function return. This means that the second 'if' statement is senseless. Check lines: 394, 401.
565: The potential null pointer is passed into 'memcpy' function. Inspect the first argument. Check lines: 565, 564.
sw_model.c:
215: The 'model' pointer was used unsafely after it was verified against nullptr. Check lines: 210, 215.
985: The 'header->lumps[12].filelen / sizeof (int)' expression was implicitly cast from 'size_t' type to 'float' type. Consider utilizing an explicit type cast to avoid the loss of a fractional part. An example: double A = (double)(X) / Y;.
1277: Function 'RE_BeginRegistration' argument 1 names different: declaration 'map' definition 'model'.
sw_surf.c:
239: There might be dereferencing of a potential null pointer 'sc_base'. Check lines: 239, 236.
sw_main.c:
1345: The if condition is the same as the previous if condition
1466: Function 'R_GammaCorrectAndSetPalette' argument 1 names different: declaration 'pal' definition 'palette'
2063: The 'swap_buffers' pointer in the expression could be nullptr. In such case, resulting value of arithmetic operations on this pointer will be senseless and it should not be used. Check lines: 2063, 2061.
sw_aclip.c:
180: Variable 'j' is reassigned a value before the old one has been used.
sw_alias.c:
209: Function 'R_AliasTransformVector' argument 3 names different: declaration 'm' definition 'xf'.
sw_draw.c:
78: Function 'RE_Draw_CharScaled' argument 3 names different: declaration 'c' definition 'num'.
149: Function 'RE_Draw_GetPicSize' argument 3 names different: declaration 'name' definition 'pic'.
173: The scope of the variable 'u' can be reduced.
267: Function 'RE_Draw_PicScaled' argument 4 names different: declaration 'factor' definition 'scale'.
sw_scan.c
593: Function 'D_DrawSpansPow2' argument 1 names different: declaration 'pspans' definition 'pspan'.
745: Function 'D_DrawZSpans' argument 1 names different: declaration 'pspans' definition 'pspan'.
Save current player position and compare with a position in the previous
frame, if position is same refresh only changed rectangle in zbuffer.
zBuffer can be damaged by models, particles and static transparent spans.
zBuffer damage is not useful for the screen refresh minimize for now,
as result of explosion can change texture light value.