From a723567a3a4a32a1f7167bcb049aeea5b69ab7cf Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" Date: Thu, 30 Dec 2021 21:59:08 +0000 Subject: [PATCH 1/9] Add manylinux_2_24 for building --- makepanda/makepanda.py | 7 +++++++ makepanda/makewheel.py | 2 ++ 2 files changed, 9 insertions(+) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 9e8186fd78..018b57029b 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -497,6 +497,13 @@ elif target == 'linux' and (os.path.isfile("/lib/libc-2.17.so") or os.path.isfil else: PLATFORM = 'manylinux2014-i686' +elif target == 'linux' and (os.path.isfile("/lib/i386-linux-gnu/libc-2.24.so") or os.path.isfile("/lib/x86_64/libc-2.24.so")) and os.path.isdir("/opt/python"): + # Same sloppy check for manylinux_2_24. + if GetTargetArch() in ('x86_64', 'amd64'): + PLATFORM = 'manylinux_2_24-x86_64' + else: + PLATFORM = 'manylinux_2_24-i686' + elif not CrossCompiling(): if HasTargetArch(): # Replace the architecture in the platform string. diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 771a9eb41a..124c44a713 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -558,6 +558,8 @@ def makewheel(version, output_dir, platform=None): platform = platform.replace("linux", "manylinux2010") elif os.path.isfile("/lib/libc-2.17.so") or os.path.isfile("/lib64/libc-2.17.so"): platform = platform.replace("linux", "manylinux2014") + elif os.path.isfile("/lib/i386-linux-gnu/libc-2.24.so") or os.path.isfile("/lib/x86_64/libc-2.24.so"): + platform = platform.replace("linux", "manylinux_2_24") platform = platform.replace('-', '_').replace('.', '_') From ce0d020cfd22f6f47b8b5cf265222e958ab313f0 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 31 Dec 2021 13:10:20 +0100 Subject: [PATCH 2/9] makepanda: Add handling for Windows 11 SDK --- README.md | 2 +- makepanda/makepanda.py | 2 +- makepanda/makepandacore.py | 12 +++++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 63b493dfc2..1b3cd3d1bf 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Windows You can build Panda3D with the Microsoft Visual C++ 2015, 2017, 2019 or 2022 compiler, which can be downloaded for free from the [Visual Studio site](https://visualstudio.microsoft.com/downloads/). -You will also need to install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk), +You will also need to install the [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk), and if you intend to target Windows XP, you will also need the Windows 7.1A SDK (which can be installed from the Visual Studio Installer). diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 018b57029b..86011cb217 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -159,7 +159,7 @@ def usage(problem): print(" --nothing (disable every third-party lib)") print(" --everything (enable every third-party lib)") print(" --directx-sdk=X (specify version of DirectX SDK to use: jun2010, aug2009, mar2009, aug2006)") - print(" --windows-sdk=X (specify Windows SDK version, eg. 7.0, 7.1 or 10. Default is 7.1)") + print(" --windows-sdk=X (specify Windows SDK version, eg. 7.0, 7.1, 10 or 11. Default is 7.1)") print(" --msvc-version=X (specify Visual C++ version, eg. 10, 11, 12, 14, 14.1, 14.2, 14.3. Default is 14)") print(" --use-icl (experimental setting to use an intel compiler instead of MSVC on Windows)") print("") diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 21ec31f5f9..1ecf349fb1 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2377,7 +2377,7 @@ def SdkLocateWindows(version = '7.1'): if version == '10': version = '10.0' - if version.startswith('10.') and version.count('.') == 1: + if (version.startswith('10.') and version.count('.') == 1) or version == '11': # Choose the latest version of the Windows 10 SDK. platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10") @@ -2386,7 +2386,13 @@ def SdkLocateWindows(version = '7.1'): platsdk = "C:\\Program Files (x86)\\Windows Kits\\10\\" if platsdk and os.path.isdir(platsdk): + min_version = (10, 0, 0) + if version == '11': + version = '10.0' + min_version = (10, 0, 22000) + incdirs = glob.glob(os.path.join(platsdk, 'Include', version + '.*.*')) + max_version = () for dir in incdirs: verstring = os.path.basename(dir) @@ -2404,7 +2410,7 @@ def SdkLocateWindows(version = '7.1'): continue vertuple = tuple(map(int, verstring.split('.'))) - if vertuple > max_version: + if vertuple > max_version and vertuple > min_version: version = verstring max_version = vertuple @@ -2900,7 +2906,7 @@ def SetupVisualStudioEnviron(): elif not win_kit.endswith('\\'): win_kit += '\\' - for vnum in 10150, 10240, 10586, 14393, 15063, 16299, 17134, 17763, 18362, 19041: + for vnum in 10150, 10240, 10586, 14393, 15063, 16299, 17134, 17763, 18362, 19041, 20348, 22000: version = "10.0.{0}.0".format(vnum) if os.path.isfile(win_kit + "Include\\" + version + "\\ucrt\\assert.h"): print("Using Universal CRT %s" % (version)) From ecc6fb6b0c260cbcad3cea98a0ec445dfa024980 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 31 Dec 2021 13:21:08 +0100 Subject: [PATCH 3/9] dxgsg9: Implement ability to get screenshot from multisample backbuffer Fixes #1225 --- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 0138463260..963cf96141 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -2070,6 +2070,35 @@ do_framebuffer_copy_to_ram(Texture *tex, int view, int z, backbuffer -> GetDesc (&surface_description); + // We can't directly call GetRenderTargetData on a multisampled buffer. + // Instead, blit it into a temporary target. + if (surface_description.MultiSampleType != D3DMULTISAMPLE_NONE) { + IDirect3DSurface9 *resolved; + hr = _d3d_device->CreateRenderTarget(surface_description.Width, + surface_description.Height, + surface_description.Format, + D3DMULTISAMPLE_NONE, 0, FALSE, + &resolved, nullptr); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "CreateRenderTarget failed" << D3DERRORSTRING(hr) << "\n"; + backbuffer->Release(); + return false; + } + + _d3d_device->StretchRect(backbuffer, nullptr, resolved, nullptr, D3DTEXF_NONE); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "StretchRect failed" << D3DERRORSTRING(hr) << "\n"; + backbuffer->Release(); + resolved->Release(); + return false; + } + + backbuffer->Release(); + backbuffer = resolved; + } + pool = D3DPOOL_SYSTEMMEM; hr = _d3d_device->CreateOffscreenPlainSurface( surface_description.Width, From 1e6569e678eeb808ff3cb5b008083f718f83e7cf Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 31 Dec 2021 22:59:01 +0100 Subject: [PATCH 4/9] dxgsg9: Fix issues with luminance textures and ATI1 compression Fixes #1198 --- panda/src/dxgsg9/dxTextureContext9.cxx | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/panda/src/dxgsg9/dxTextureContext9.cxx b/panda/src/dxgsg9/dxTextureContext9.cxx index 70c9db7803..5e2fc2d94b 100644 --- a/panda/src/dxgsg9/dxTextureContext9.cxx +++ b/panda/src/dxgsg9/dxTextureContext9.cxx @@ -427,10 +427,26 @@ create_texture(DXScreenData &scrn) { } if (compress_texture) { - if (num_color_channels == 1) { - CHECK_FOR_FMT(ATI1); - } else if (num_alpha_bits == 0 && num_color_channels == 2) { - CHECK_FOR_FMT(ATI2); + // The ATI1 and ATI2 formats can't be compressed by the driver. + // Only choose them if we can compress them on the CPU. + // Also, don't choose ATI for a luminance texture, since it gets read as + // a texture with just a red channel. + if (num_alpha_bits == 0 && !needs_luminance) { + if (num_color_channels == 1) { + if (scrn._supported_tex_formats_mask & ATI1_FLAG) { + if (tex->compress_ram_image(Texture::CM_rgtc)) { + target_pixel_format = D3DFMT_ATI1; + goto found_matching_format; + } + } + } else if (num_color_channels == 2) { + if (scrn._supported_tex_formats_mask & ATI2_FLAG) { + if (tex->compress_ram_image(Texture::CM_rgtc)) { + target_pixel_format = D3DFMT_ATI2; + goto found_matching_format; + } + } + } } if (num_alpha_bits <= 1) { CHECK_FOR_FMT(DXT1); From 72bf9e7fd10c550b109c727e494a0aaad73951b7 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 1 Jan 2022 12:08:00 +0100 Subject: [PATCH 5/9] device: Map FrSky RC controller as flight stick instead of gamepad Reverts f01399bba875929d0f25c460c290f584f0f81608 --- panda/src/device/evdevInputDevice.cxx | 2 ++ panda/src/device/winRawInputDevice.cxx | 23 ++++------------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/panda/src/device/evdevInputDevice.cxx b/panda/src/device/evdevInputDevice.cxx index 9cf94e1dfc..c4d293eb91 100644 --- a/panda/src/device/evdevInputDevice.cxx +++ b/panda/src/device/evdevInputDevice.cxx @@ -113,6 +113,8 @@ static const struct DeviceMapping { {0x046d, 0xc629, InputDevice::DeviceClass::spatial_mouse, 0}, // 3Dconnexion Space Mouse Pro {0x046d, 0xc62b, InputDevice::DeviceClass::spatial_mouse, 0}, + // FrSky Simulator + {0x0483, 0x5720, InputDevice::DeviceClass::flight_stick, 0}, {0}, }; diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 6bcb2ebf9b..421d3c573c 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -38,9 +38,6 @@ enum QuirkBits : int { // Axes on the right stick are swapped, using x for y and vice versa. QB_right_axes_swapped = 64, - - // Using an RC (drone) controller as a gamepad instead of a flight stick - QB_rc_controller = 128, }; // Some nonstandard gamepads have different button mappings. @@ -89,7 +86,7 @@ static const struct DeviceMapping { {"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"} }, // FrSky Simulator - {0x0483, 0x5720, InputDevice::DeviceClass::gamepad, QB_rc_controller, + {0x0483, 0x5720, InputDevice::DeviceClass::flight_stick, 0, {0} }, {0}, @@ -441,11 +438,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { switch (usage) { case HID_USAGE_GENERIC_X: if (_device_class == DeviceClass::gamepad) { - if (quirks & QB_rc_controller) { - axis = Axis::right_x; - } else { - axis = Axis::left_x; - } + axis = Axis::left_x; } else if (_device_class == DeviceClass::flight_stick) { axis = Axis::roll; } else { @@ -454,12 +447,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { break; case HID_USAGE_GENERIC_Y: if (_device_class == DeviceClass::gamepad) { - if (quirks & QB_rc_controller) { - axis = Axis::right_y; - } else { - axis = Axis::left_y; - swap(cap.LogicalMin, cap.LogicalMax); - } + axis = Axis::left_y; + swap(cap.LogicalMin, cap.LogicalMax); } else if (_device_class == DeviceClass::flight_stick) { axis = Axis::pitch; } else { @@ -476,8 +465,6 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { } else { axis = InputDevice::Axis::right_x; } - } else if (quirks & QB_rc_controller) { - axis = InputDevice::Axis::left_y; } else if ((quirks & QB_no_analog_triggers) == 0) { axis = Axis::left_trigger; } @@ -500,8 +487,6 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { if ((quirks & QB_no_analog_triggers) == 0) { axis = Axis::left_trigger; } - } else if (quirks & QB_rc_controller) { - axis = Axis::left_x; } else { axis = Axis::right_x; } From 0e9ea6706686ee810eea8171b96637b324763481 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 1 Jan 2022 12:11:15 +0100 Subject: [PATCH 6/9] device: Implement correct sign extension for Windows raw devices Hopefully, fix for #1218 --- panda/src/device/winRawInputDevice.cxx | 30 ++++++++++++++++++++------ panda/src/device/winRawInputDevice.h | 6 +++--- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 421d3c573c..8448b58da4 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -405,7 +405,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { << ", UsagePage=0x" << hex << cap.UsagePage << ", Usage=0x" << cap.Range.UsageMin << "..0x" << cap.Range.UsageMax << dec << ", LogicalMin=" << cap.LogicalMin - << ", LogicalMax=" << cap.LogicalMax << "\n"; + << ", LogicalMax=" << cap.LogicalMax + << ", BitSize=" << cap.BitSize << "\n"; } } else { if (device_cat.is_debug()) { @@ -415,7 +416,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { << ", UsagePage=0x" << hex << cap.UsagePage << ", Usage=0x" << cap.NotRange.Usage << dec << ", LogicalMin=" << cap.LogicalMin - << ", LogicalMax=" << cap.LogicalMax << "\n"; + << ", LogicalMax=" << cap.LogicalMax + << ", BitSize=" << cap.BitSize << "\n"; } } @@ -428,7 +430,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { // My gamepads give this odd invalid range. if (cap.LogicalMin == 0 && cap.LogicalMax == -1) { - cap.LogicalMax = 65535; + cap.LogicalMax = (1 << cap.BitSize) - 1; is_signed = false; } @@ -562,6 +564,17 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { } } + int sign_bit = 0; + if (cap.BitSize < 32) { + if (cap.LogicalMin < 0) { + sign_bit = 1 << (cap.BitSize - 1); + } + else if (is_signed) { + //XXX is this still necessary? + sign_bit = (1 << 15); + } + } + int axis_index; if (!is_signed) { // All axes on the weird XInput-style mappings go from -1 to 1 @@ -569,7 +582,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { } else { axis_index = add_axis(axis, cap.LogicalMin, cap.LogicalMax); } - _indices[data_index] = Index::axis(axis_index, is_signed); + _indices[data_index] = Index::axis(axis_index, sign_bit); } } @@ -685,8 +698,13 @@ process_report(PCHAR ptr, size_t size) { const Index &idx = _indices[data[di].DataIndex]; if (idx._axis >= 0) { - if (idx._signed) { - axis_changed(idx._axis, (SHORT)data[di].RawValue); + if (idx._sign_bit != 0) { + // Sign extend. + int value = data[di].RawValue; + if (value & idx._sign_bit) { + value = -(value & ~idx._sign_bit); + } + axis_changed(idx._axis, value); } else { axis_changed(idx._axis, data[di].RawValue); } diff --git a/panda/src/device/winRawInputDevice.h b/panda/src/device/winRawInputDevice.h index bea8066b85..84189b506e 100644 --- a/panda/src/device/winRawInputDevice.h +++ b/panda/src/device/winRawInputDevice.h @@ -59,16 +59,16 @@ private: idx._button = index; return idx; } - static Index axis(int index, bool is_signed=true) { + static Index axis(int index, int sign_bit = 0) { Index idx; idx._axis = index; - idx._signed = is_signed; + idx._sign_bit = sign_bit; return idx; } int _button; int _axis; - bool _signed; + int _sign_bit; }; // Maps a "data index" to either button index or axis index. From 5caf0ff5d6df2f112d4a6169554bf5e45346bf16 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 1 Jan 2022 15:14:30 +0100 Subject: [PATCH 7/9] device: Correction to 0e9ea6706686ee810eea8171b96637b324763481 Fixes #1218 --- panda/src/device/winRawInputDevice.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 8448b58da4..0e1eb937bf 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -702,7 +702,7 @@ process_report(PCHAR ptr, size_t size) { // Sign extend. int value = data[di].RawValue; if (value & idx._sign_bit) { - value = -(value & ~idx._sign_bit); + value -= (idx._sign_bit << 1); } axis_changed(idx._axis, value); } else { From 500491e6c92b6a3b552a59cbe4359367a9934f8b Mon Sep 17 00:00:00 2001 From: loonaticx Date: Sat, 1 Jan 2022 15:20:57 +0100 Subject: [PATCH 8/9] CommonFilters: Documentation adjustments * State that we're using Cg shaders, ideal for clarification. * Commented out Josh's monologue since it doesn't particularly contribute to the API page * Added documentation to the setBloom function to help clarify. Closes #1200 Co-authored-by: rdb --- direct/src/filter/CommonFilters.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/direct/src/filter/CommonFilters.py b/direct/src/filter/CommonFilters.py index 26601ced2e..25715d7167 100644 --- a/direct/src/filter/CommonFilters.py +++ b/direct/src/filter/CommonFilters.py @@ -1,21 +1,21 @@ """ - Class CommonFilters implements certain common image postprocessing filters. See the :ref:`common-image-filters` page for more information about how to use these filters. -It is not ideal that these filters are all included in a single -monolithic module. Unfortunately, when you want to apply two filters -at the same time, you have to compose them into a single shader, and -the composition process isn't simply a question of concatenating them: -you have to somehow make them work together. I suspect that there -exists some fairly simple framework that would make this automatable. -However, until I write some more filters myself, I won't know what -that framework is. Until then, I'll settle for this -clunky approach. - Josh - +These filters are written in the Cg shading language. """ +# It is not ideal that these filters are all included in a single +# monolithic module. Unfortunately, when you want to apply two filters +# at the same time, you have to compose them into a single shader, and +# the composition process isn't simply a question of concatenating them: +# you have to somehow make them work together. I suspect that there +# exists some fairly simple framework that would make this automatable. +# However, until I write some more filters myself, I won't know what +# that framework is. Until then, I'll settle for this +# clunky approach. - Josh + from .FilterManager import FilterManager from .filterBloomI import BLOOM_I from .filterBloomX import BLOOM_X @@ -459,6 +459,11 @@ class CommonFilters: return True def setBloom(self, blend=(0.3,0.4,0.3,0.0), mintrigger=0.6, maxtrigger=1.0, desat=0.6, intensity=1.0, size="medium"): + """ + Applies the Bloom filter to the output. + size can either be "off", "small", "medium", or "large". + Setting size to "off" will remove the Bloom filter. + """ if (size==0): size="off" elif (size==1): size="small" elif (size==2): size="medium" @@ -542,7 +547,7 @@ class CommonFilters: return True def setBlurSharpen(self, amount=0.0): - """Enables the blur/sharpen filter. If the 'amount' parameter is 1.0, it will not have effect. + """Enables the blur/sharpen filter. If the 'amount' parameter is 1.0, it will not have any effect. A value of 0.0 means fully blurred, and a value higher than 1.0 sharpens the image.""" fullrebuild = (("BlurSharpen" in self.configuration) == False) self.configuration["BlurSharpen"] = amount From 2915c6e670e30b9581b5a2646088982654702093 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 1 Jan 2022 16:49:41 +0100 Subject: [PATCH 9/9] glgsg: Force transform_weight column to read (0, 0, 0, 1) if absent On NVIDIA cards, this doesn't seem to happen automatically. Fixes #1207 --- panda/src/glstuff/glShaderContext_src.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 450fb69367..aad4305b20 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -2591,6 +2591,11 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { _glgsg->_glVertexAttribI4ui != nullptr) { _glgsg->_glVertexAttribI4ui(p, 0, 1, 2, 3); } + else if (name == InternalName::get_transform_weight()) { + // NVIDIA doesn't seem to use to use these defaults by itself + static const GLfloat weights[4] = {0, 0, 0, 1}; + _glgsg->_glVertexAttrib4fv(p, weights); + } } }