From ed96a5270333c5344c9757393939c1a02a4dd1cc Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 20:40:55 +0100 Subject: [PATCH 01/15] cocoa: cautiously enable sRGB framebuffers on macOS [skip ci] --- panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm b/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm index 26d4dbdf71..b584d02a2c 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm @@ -134,6 +134,12 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for if (accelerated) { properties.set_force_hardware(1); } + + // Cautiously setting this to true. It appears that macOS framebuffers are + // sRGB-capable, but I don't really know how to verify this. + if (color_size == 32 && !color_float) { + properties.set_srgb_color(true); + } } /** From 33385facfbf469817fcdd80e8de0eddc6989fd88 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Mon, 29 Oct 2018 15:29:41 -0600 Subject: [PATCH 02/15] dxgsg9: Delete dead dxInput9.{cxx,h} files This file isn't compiled, and I'm pretty sure never has been compiled. The dependence on "config_wdxdisplay9.h" (which has never existed) and absence of any commits that address its functionality reinforce the idea that this is actually just dead code. This seems like an artifact copied over from the DX8 code, that nobody cared enough to get working or delete. --- panda/src/dxgsg9/dxInput9.cxx | 269 -------------------------- panda/src/dxgsg9/dxInput9.h | 40 ---- panda/src/dxgsg9/wdxGraphicsWindow9.h | 1 - 3 files changed, 310 deletions(-) delete mode 100644 panda/src/dxgsg9/dxInput9.cxx delete mode 100644 panda/src/dxgsg9/dxInput9.h diff --git a/panda/src/dxgsg9/dxInput9.cxx b/panda/src/dxgsg9/dxInput9.cxx deleted file mode 100644 index 17d5b2f88e..0000000000 --- a/panda/src/dxgsg9/dxInput9.cxx +++ /dev/null @@ -1,269 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file dxInput9.cxx - * @author angelina jolie - * @date 1999-10-07 - */ - -#include "config_wdxdisplay9.h" -#include "dxInput9.h" - -#define AXIS_RESOLUTION 2000 // use this many levels of resolution by default (could be more if needed and device supported it) -#define AXIS_RANGE_CENTERED // if defined, axis range is centered on 0, instead of starting on 0 - -using std::endl; - -BOOL CALLBACK EnumGameCtrlsCallback( const DIDEVICEINSTANCE* pdidInstance, - VOID* pContext ) { - DI_DeviceInfos *pDevInfos = (DI_DeviceInfos *)pContext; - - (*pDevInfos).push_back(*pdidInstance); - - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "Found DevType 0x" << (void*)pdidInstance->dwDevType << ": " << pdidInstance->tszInstanceName << ": " << pdidInstance->tszProductName <Unacquire(); - SAFE_RELEASE(_DeviceList[i]); - } - - // bugbug: need to handle this if(_JoystickPollTimer!=NULL) KillTimer(...) - - SAFE_RELEASE(_pDInput9); - if(_hDInputDLL) { - FreeLibrary(_hDInputDLL); - _hDInputDLL=nullptr; - } -} - -bool DInput9Info::InitDirectInput() { - HRESULT hr; - - // assumes dx9 exists use dynamic load so non-dinput programs don't have - // to load dinput - #define DLLNAME "dinput9.dll" - #define DINPUTCREATE "DirectInput9Create" - - HINSTANCE _hDInputDLL = LoadLibrary(DLLNAME); - if(_hDInputDLL == 0) { - wdxdisplay_cat.fatal() << "LoadLibrary(" << DLLNAME <<") failed!, error=" << GetLastError() << endl; - exit(1); - } - - typedef HRESULT (WINAPI * LPDIRECTINPUT9CREATE)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); - LPDIRECTINPUT9CREATE pDInputCreate9; - - pDInputCreate9 = (LPDIRECTINPUT9CREATE) GetProcAddress(_hDInputDLL,DINPUTCREATE); - if(pDInputCreate9 == nullptr) { - wdxdisplay_cat.fatal() << "GetProcAddr failed for " << DINPUTCREATE << endl; - exit(1); - } - - // Register with the DirectInput subsystem and get a pointer to a - // IDirectInput interface we can use. Create a DInput object - if( FAILED( hr = (*pDInputCreate9)(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, - IID_IDirectInput9, (VOID**)&_pDInput9, nullptr ) ) ) { - wdxdisplay_cat.error() << DINPUTCREATE << "failed" << D3DERRORSTRING(hr); - return false; - } - - // enum all the joysticks,etc (but not keybdmouse) - if( FAILED( hr = _pDInput9->EnumDevices(DI9DEVCLASS_GAMECTRL, - EnumGameCtrlsCallback, - (LPVOID)&_DevInfos, DIEDFL_ATTACHEDONLY ) ) ) { - wdxdisplay_cat.error() << "EnumDevices failed" << D3DERRORSTRING(hr); - return false; - } - - return true; -} - -bool DInput9Info::CreateJoystickOrPad(HWND _window) { - bool bFoundDev = false; - UINT devnum=0; - char *errstr=nullptr; - - // look through the list for the first joystick or gamepad - for(;devnum<_DevInfos.size();devnum++) { - DWORD devType = GET_DIDEVICE_TYPE(_DevInfos[devnum].dwDevType); - if((devType==DI9DEVTYPE_GAMEPAD) ||(devType==DI9DEVTYPE_JOYSTICK)) { - bFoundDev=true; - break; - } - } - - if(!bFoundDev) { - wdxdisplay_cat.error() << "Cant find an attached Joystick or GamePad!\n"; - return false; - } - - LPDIRECTINPUTDEVICE9 pJoyDevice; - - // Obtain an interface to the enumerated joystick. - HRESULT hr = _pDInput9->CreateDevice(_DevInfos[devnum].guidInstance, &pJoyDevice, nullptr ); - if(FAILED(hr)) { - errstr="CreateDevice"; - goto handle_error; - } - - assert(pJoyDevice!=nullptr); - _DeviceList.push_back(pJoyDevice); - - // Set the data format to "simple joystick" - a predefined data format A - // data format specifies which controls on a device we are interested in, - // and how they should be reported. This tells DInput that we will be - // passing a DIJOYSTATE2 structure to - // IDirectInputDevice::GetDeviceState(). - hr = pJoyDevice->SetDataFormat(&c_dfDIJoystick2); - if(FAILED(hr)) { - errstr="SetDataFormat"; - goto handle_error; - } - - // must be called AFTER SetDataFormat to get all the proper flags - DX_DECLARE_CLEAN(DIDEVCAPS, DIDevCaps); - hr = pJoyDevice->GetCapabilities(&DIDevCaps); - assert(SUCCEEDED(hr)); - - _DevCaps.push_back(DIDevCaps); - - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "Joy/Pad has " << DIDevCaps.dwAxes << " Axes, " << DIDevCaps.dwButtons << " Buttons, " << DIDevCaps.dwPOVs << " POVs" << endl; - - // Set the cooperative level to let DInput know how this device should - // interact with the system and with other DInput applications. - hr = pJoyDevice->SetCooperativeLevel( _window, DISCL_EXCLUSIVE | DISCL_FOREGROUND); - if(FAILED(hr)) { - errstr="SetCooperativeLevel"; - goto handle_error; - } - - // set the minmax values property for discovered axes. - hr = pJoyDevice->EnumObjects(EnumObjectsCallbackJoystick, (LPVOID)pJoyDevice, DIDFT_AXIS); - if(FAILED(hr)) { - errstr="EnumObjects"; - goto handle_error; - } - - return true; - - handle_error: - wdxdisplay_cat.error() << errstr << " failed for (" << _DevInfos[devnum].tszInstanceName << ":" << _DevInfos[devnum].tszProductName << ")" << D3DERRORSTRING(hr); - return false; -} - -// --------------------------------------------------------------------------- -// -- Name: EnumObjectsCallback() Desc: Callback function for enumerating -// objects (axes, buttons, POVs) on a joystick. This function enables user -// interface elements for objects that are found to exist, and scales axes -// minmax values. ----------------------------------------------------------- -// ------------------ -BOOL CALLBACK EnumObjectsCallbackJoystick( const DIDEVICEOBJECTINSTANCE* pdidoi, - VOID* pContext ) { - - LPDIRECTINPUTDEVICE9 pJoyDevice = (LPDIRECTINPUTDEVICE9) pContext; - HRESULT hr; - - // For axes that are returned, set the DIPROP_RANGE property for the - // enumerated axis in order to scale minmax values. - if( pdidoi->dwType & DIDFT_AXIS ) { - DIPROPRANGE diprg; - diprg.diph.dwSize = sizeof(DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYID; - diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis - - #ifdef AXIS_RANGE_CENTERED - diprg.lMin = -AXIS_RESOLUTION/2; - diprg.lMax = +AXIS_RESOLUTION/2; - #else - diprg.lMin = 0; - diprg.lMax = +AXIS_RESOLUTION; - #endif - - // Set the range for the axis - hr = pJoyDevice->SetProperty( DIPROP_RANGE, &diprg.diph); - if(FAILED(hr)) { - wdxdisplay_cat.error() << "SetProperty on axis failed" << D3DERRORSTRING(hr); - return DIENUM_STOP; - } - } - - return DIENUM_CONTINUE; -} - -bool DInput9Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) { - LPDIRECTINPUTDEVICE9 pJoystick = _DeviceList[devnum]; - assert(pJoystick!=nullptr); - HRESULT hr; - char *errstr; - - // Poll the device to read the current state - - hr = pJoystick->Poll(); - - if( FAILED(hr) ) { - // DInput is telling us that the input stream has been interrupted. - // We aren't tracking any state between polls, so we don't have any - // special reset that needs to be done. We just re-acquire and try - // again. - - if((hr==DIERR_NOTACQUIRED)||(hr == DIERR_INPUTLOST)) { - hr = pJoystick->Acquire(); - - if(FAILED(hr)) { - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "Acquire failed" << D3DERRORSTRING(hr); - - // hr may be DIERR_OTHERAPPHASPRIO or other errors. This may - // occur when the app is minimized or in the process of - // switching, so just try again later - return false; - } - - hr = pJoystick->Poll(); - if(FAILED(hr)) { - // should never happen! - errstr = "Poll after successful Acquire failed"; - goto handle_error; - } - } else { - errstr = "Unknown Poll failure"; - goto handle_error; - } - } - - // should we make a vector of devstate dataformats to generalize this fn - // for all device types? - - // Get the input's device state - hr = pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js); - if(FAILED(hr)) { - errstr = "GetDeviceState failed"; - goto handle_error; - } - - return true; - - handle_error: - wdxdisplay_cat.fatal() << errstr << D3DERRORSTRING(hr); - return false; -} diff --git a/panda/src/dxgsg9/dxInput9.h b/panda/src/dxgsg9/dxInput9.h deleted file mode 100644 index 9614a2627d..0000000000 --- a/panda/src/dxgsg9/dxInput9.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file dxInput9.h - * @author blllyjo - * @date 1999-10-07 - */ - -#ifndef DXINPUT9_H -#define DXINPUT9_H - -#define DIRECTINPUT_VERSION 0x900 -#include -typedef std::vector DI_DeviceInfos; -typedef std::vector DI_DeviceObjInfos; - -class DInput9Info { -public: - DInput9Info(); - ~DInput9Info(); - bool InitDirectInput(); - bool CreateJoystickOrPad(HWND _window); - bool ReadJoystick(int devnum, DIJOYSTATE2 &js); - - HINSTANCE _hDInputDLL; - UINT_PTR _JoystickPollTimer; - LPDIRECTINPUT8 _pDInput9; - DI_DeviceInfos _DevInfos; - // arrays for all created devices. Should probably put these together in a - // struct, along with the data fmt info - std::vector _DeviceList; - std::vector _DevCaps; -}; - -#endif diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.h b/panda/src/dxgsg9/wdxGraphicsWindow9.h index 391fb9d7e9..42a6fe6763 100644 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.h +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.h @@ -17,7 +17,6 @@ #include "pandabase.h" #include "winGraphicsWindow.h" #include "dxGraphicsStateGuardian9.h" -#include "dxInput9.h" #include "wdxGraphicsPipe9.h" class wdxGraphicsPipe9; From 2ed4cd7ce6359e608f3bbd3a3a348ab88d1f7bff Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 29 Oct 2018 22:38:00 +0100 Subject: [PATCH 03/15] cppparser: fix CPPStructType::is_trivial() for eg. ButtonHandle --- dtool/src/cppparser/cppStructType.cxx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dtool/src/cppparser/cppStructType.cxx b/dtool/src/cppparser/cppStructType.cxx index d0707c4404..745abab586 100644 --- a/dtool/src/cppparser/cppStructType.cxx +++ b/dtool/src/cppparser/cppStructType.cxx @@ -306,7 +306,6 @@ is_trivial() const { } // Now look for functions that are virtual or con/destructors. - bool is_default_constructible = true; CPPScope::Functions::const_iterator fi; for (fi = _scope->_functions.begin(); fi != _scope->_functions.end(); ++fi) { CPPFunctionGroup *fgroup = (*fi).second; @@ -343,9 +342,6 @@ is_trivial() const { // Same for the default constructor. return false; } - // The presence of a non-default constructor makes the class not - // default-constructible. - is_default_constructible = false; } if (fgroup->_name == "operator =") { @@ -356,7 +352,7 @@ is_trivial() const { } // Finally, the class must be default-constructible. - return is_default_constructible; + return is_default_constructible(V_public); } /** From ad3b145951654a76c90bd001c0b1e10dc02d3e87 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 29 Oct 2018 22:39:17 +0100 Subject: [PATCH 04/15] interrogate: generated property getter should copy in some cases This is to fix eg. public ButtonHandle members from being returned as const reference, which means they won't outlive the struct they are accessed on, a recipe for obscure crashes. The is_trivial() criterium for this to apply is admittedly really arbitrary; I haven't really figured out what the right criterium should be, but it's better than hardcoding ButtonHandle. --- dtool/src/interrogate/interrogateBuilder.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dtool/src/interrogate/interrogateBuilder.cxx b/dtool/src/interrogate/interrogateBuilder.cxx index 15607c95ea..b740d59e1a 100644 --- a/dtool/src/interrogate/interrogateBuilder.cxx +++ b/dtool/src/interrogate/interrogateBuilder.cxx @@ -1389,7 +1389,8 @@ scan_element(CPPInstance *element, CPPStructType *struct_type, // We can only generate a getter and a setter if we can talk about the // type it is. - if (parameter_type->as_struct_type() != nullptr) { + if (parameter_type->as_struct_type() != nullptr && + !parameter_type->is_trivial()) { // Wrap the type in a const reference. parameter_type = TypeManager::wrap_const_reference(parameter_type); } From b45f6fbbed3534e0c0c79f4fd783e5169809e414 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Mon, 29 Oct 2018 17:50:22 -0600 Subject: [PATCH 05/15] dxgsg9: Remove DirectX 9.1 "detection" code This method of checking for pnhpast.dll was actually for DirectX 8.1 (see a16fe56c7) and its presence in the DX9 code is largely due to the copy-and-paste nature of how the DX9 GSG was created from the DX8 code. --- panda/src/dxgsg9/dxgsg9base.h | 1 - panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 24 ++---------------------- panda/src/dxgsg9/wdxGraphicsPipe9.h | 1 - panda/src/dxgsg9/wdxGraphicsWindow9.cxx | 3 +-- 4 files changed, 3 insertions(+), 26 deletions(-) diff --git a/panda/src/dxgsg9/dxgsg9base.h b/panda/src/dxgsg9/dxgsg9base.h index b0e2b9dfef..430876dff5 100644 --- a/panda/src/dxgsg9/dxgsg9base.h +++ b/panda/src/dxgsg9/dxgsg9base.h @@ -211,7 +211,6 @@ struct DXScreenData { bool _is_tnl_device; bool _can_use_hw_vertex_shaders; bool _can_use_pixel_shaders; - bool _is_dx9_1; UINT _supported_screen_depths_mask; UINT _supported_tex_formats_mask; bool _supports_rgba16f_texture_format; diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 6c85c6652f..ce8d33165f 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -193,30 +193,10 @@ init() { } // Create a Direct3D object. + __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION); - // these were taken from the 8.0 and 8.1 d3d8.h SDK headers - __is_dx9_1 = false; - -#define D3D_SDK_VERSION_9_0 D3D_SDK_VERSION -#define D3D_SDK_VERSION_9_1 D3D_SDK_VERSION - - // are we using 9.0 or 9.1? - WIN32_FIND_DATA TempFindData; - HANDLE hFind; - char tmppath[_MAX_PATH + 128]; - GetSystemDirectory(tmppath, MAX_PATH); - strcat(tmppath, "\\dpnhpast.dll"); - hFind = FindFirstFile (tmppath, &TempFindData); - if (hFind != INVALID_HANDLE_VALUE) { - FindClose(hFind); -// ??? This was from DX8 __is_dx9_1 = true; - __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_1); - } else { - __is_dx9_1 = false; - __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_0); - } if (__d3d9 == nullptr) { - wdxdisplay9_cat.error() << "Direct3DCreate9(9." << (__is_dx9_1 ? "1" : "0") << ") failed!, error = " << GetLastError() << endl; + wdxdisplay9_cat.error() << "Direct3DCreate9 failed!, error = " << GetLastError() << endl; // release_gsg(); goto error; } diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.h b/panda/src/dxgsg9/wdxGraphicsPipe9.h index 2d9eea18b0..ff25433e79 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.h +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.h @@ -93,7 +93,6 @@ private: typedef pvector CardIDs; CardIDs _card_ids; - bool __is_dx9_1; public: static TypeHandle get_class_type() { diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index 3207c81189..07a265a97c 100644 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -878,7 +878,7 @@ choose_device() { LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion; wdxdisplay9_cat.info() - << "D3D9." << (dxpipe->__is_dx9_1 ?"1":"0") << " Adapter[" << i << "]: " << adapter_info.Description + << "D3D9 Adapter[" << i << "]: " << adapter_info.Description << ", Driver: " << adapter_info.Driver << ", DriverVersion: (" << HIWORD(DrvVer->HighPart) << "." << LOWORD(DrvVer->HighPart) << "." << HIWORD(DrvVer->LowPart) << "." << LOWORD(DrvVer->LowPart) @@ -979,7 +979,6 @@ consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) { nassertr(_dxgsg != nullptr, false); _wcontext._d3d9 = _d3d9; - _wcontext._is_dx9_1 = dxpipe->__is_dx9_1; _wcontext._card_id = device_info->cardID; // could this change by end? bool bWantStencil = (_fb_properties.get_stencil_bits() > 0); From 8d3576607ead02f5479b89994711cadd62c55364 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 30 Oct 2018 14:10:10 +0100 Subject: [PATCH 06/15] makepanda: remove INSTALLING-PLUGINS.TXT from installer.nsi [skip ci] --- makepanda/installer.nsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi index 976bfd84f5..1dab5196da 100644 --- a/makepanda/installer.nsi +++ b/makepanda/installer.nsi @@ -589,7 +589,6 @@ Section "3ds Max plug-ins" SecMaxPlugins File /nonfatal /r "${BUILT}\plugins\*.dle" File /nonfatal /r "${BUILT}\plugins\*.dlo" File /nonfatal /r "${BUILT}\plugins\*.ms" - File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT" SectionEnd !endif @@ -604,7 +603,6 @@ Section "Maya plug-ins" SecMayaPlugins SetOutPath $INSTDIR\plugins File /nonfatal /r "${BUILT}\plugins\*.mll" File /nonfatal /r "${BUILT}\plugins\*.mel" - File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT" SectionEnd !endif From 63484c83cbd667949ef8af03a53e84479b76b100 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 31 Oct 2018 21:25:03 +0100 Subject: [PATCH 07/15] pipeline: CycleData should always inherit from MemoryBase We need to guarantee that CData classes are aligned properly, even if DO_PIPELINING is not enabled. --- panda/src/pipeline/cycleData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/pipeline/cycleData.h b/panda/src/pipeline/cycleData.h index ef21ad7a33..c2bcef4073 100644 --- a/panda/src/pipeline/cycleData.h +++ b/panda/src/pipeline/cycleData.h @@ -44,7 +44,7 @@ class EXPCL_PANDA_PIPELINE CycleData : public NodeReferenceCount // If we are *not* compiling in pipelining support, the CycleData object is // stored directly within its containing classes, and hence should not be a // ReferenceCount object. -class EXPCL_PANDA_PIPELINE CycleData +class EXPCL_PANDA_PIPELINE CycleData : public MemoryBase #endif // DO_PIPELINING { From 14411f592eac2af241cce8ca1fa7874bb3406cfe Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 16:24:06 +0100 Subject: [PATCH 08/15] Remove obsolete .init files in configfiles directories These look like they were part of some now-defunct Disney tool. --- direct/src/configfiles/direct.init | 9 --------- panda/src/configfiles/panda.init | 10 ---------- pandatool/src/configfiles/pandatool.init | 1 - 3 files changed, 20 deletions(-) delete mode 100644 direct/src/configfiles/direct.init delete mode 100644 panda/src/configfiles/panda.init delete mode 100644 pandatool/src/configfiles/pandatool.init diff --git a/direct/src/configfiles/direct.init b/direct/src/configfiles/direct.init deleted file mode 100644 index 16eb87325c..0000000000 --- a/direct/src/configfiles/direct.init +++ /dev/null @@ -1,9 +0,0 @@ -ATTACH dmodels -ATTACH panda -MODREL ETC_PATH etc -DOCSH set parent=`dirname $DIRECT` -DOCSH if ( ${?PANDA_ROOT} ) then -DOCSH setenv PYTHONPATH "${PYTHONPATH};"`cygpath -w "$parent"` -DOCSH else -DOCSH setenv PYTHONPATH "${PYTHONPATH}:$parent" -DOCSH endif diff --git a/panda/src/configfiles/panda.init b/panda/src/configfiles/panda.init deleted file mode 100644 index 6256527d14..0000000000 --- a/panda/src/configfiles/panda.init +++ /dev/null @@ -1,10 +0,0 @@ -SETABS PANDA_VER 0.8 -MODREL ETC_PATH built/etc -DOCSH if ( ! $?CFG_PATH ) then -DOCSH setenv CFG_PATH ~ -DOCSH setenv CFG_PATH ". ${CFG_PATH} /usr/local/etc" -DOCSH endif -DOSH if [ -z "$CFG_PATH" ]; then -DOSH CFG_PATH=". $HOME /usr/local/etc" -DOSH export CFG_PATH -DOSH fi diff --git a/pandatool/src/configfiles/pandatool.init b/pandatool/src/configfiles/pandatool.init deleted file mode 100644 index 615e010d42..0000000000 --- a/pandatool/src/configfiles/pandatool.init +++ /dev/null @@ -1 +0,0 @@ -ATTACH panda From 604366aaa74259d32d54d2530bac3810ad35d687 Mon Sep 17 00:00:00 2001 From: loblao Date: Tue, 30 Oct 2018 12:13:58 -0300 Subject: [PATCH 09/15] CollisionEntrySorter: Check if entry has surface point Fixes #435 --- panda/src/collide/collisionHandlerQueue.cxx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/panda/src/collide/collisionHandlerQueue.cxx b/panda/src/collide/collisionHandlerQueue.cxx index 75761362bd..0f6acaba52 100644 --- a/panda/src/collide/collisionHandlerQueue.cxx +++ b/panda/src/collide/collisionHandlerQueue.cxx @@ -22,10 +22,15 @@ class CollisionEntrySorter { public: CollisionEntrySorter(CollisionEntry *entry) { _entry = entry; - LVector3 vec = - entry->get_surface_point(entry->get_from_node_path()) - - entry->get_from()->get_collision_origin(); - _dist2 = vec.length_squared(); + if (entry->has_surface_point()) { + LVector3 vec = + entry->get_surface_point(entry->get_from_node_path()) - + entry->get_from()->get_collision_origin(); + _dist2 = vec.length_squared(); + } + else { + _dist2 = make_inf((PN_stdfloat)0); + } } bool operator < (const CollisionEntrySorter &other) const { return _dist2 < other._dist2; From 763049ac81345da33362e354a0af27f3d85c5d12 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 17:05:33 +0100 Subject: [PATCH 10/15] event: fix incorrect include in asyncFuture_ext.h --- panda/src/event/asyncFuture_ext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/event/asyncFuture_ext.h b/panda/src/event/asyncFuture_ext.h index 21786ee17b..94f0b3d60b 100644 --- a/panda/src/event/asyncFuture_ext.h +++ b/panda/src/event/asyncFuture_ext.h @@ -16,7 +16,7 @@ #include "extension.h" #include "py_panda.h" -#include "modelLoadRequest.h" +#include "asyncFuture.h" #ifdef HAVE_PYTHON From bc22f5781b77eb85f0dda10c638ac1f8667c9732 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 20:33:08 +0100 Subject: [PATCH 11/15] shader: supports preprocessed GLSL shaders in Shader.make() Fixes #436 --- panda/src/gobj/shader.cxx | 317 +++++++++++++++++++++++++++++--------- panda/src/gobj/shader.h | 13 +- 2 files changed, 254 insertions(+), 76 deletions(-) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 220bd56ed2..4c79745e85 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -2468,6 +2468,96 @@ read(const ShaderFile &sfile, BamCacheRecord *record) { return true; } +/** + * Loads the shader from the given string(s). Returns a boolean indicating + * success or failure. + */ +bool Shader:: +load(const ShaderFile &sbody, BamCacheRecord *record) { + _filename = ShaderFile("created-shader"); + _fullpath = Filename(); + _text._separate = sbody._separate; + + if (sbody._separate) { + if (_language == SL_none) { + shader_cat.error() + << "No shader language was specified!\n"; + return false; + } + + if (!sbody._vertex.empty() && + !do_load_source(_text._vertex, sbody._vertex, record)) { + return false; + } + if (!sbody._fragment.empty() && + !do_load_source(_text._fragment, sbody._fragment, record)) { + return false; + } + if (!sbody._geometry.empty() && + !do_load_source(_text._geometry, sbody._geometry, record)) { + return false; + } + if (!sbody._tess_control.empty() && + !do_load_source(_text._tess_control, sbody._tess_control, record)) { + return false; + } + if (!sbody._tess_evaluation.empty() && + !do_load_source(_text._tess_evaluation, sbody._tess_evaluation, record)) { + return false; + } + if (!sbody._compute.empty() && + !do_load_source(_text._compute, sbody._compute, record)) { + return false; + } + + } else { + if (!do_load_source(_text._shared, sbody._shared, record)) { + return false; + } + + // Determine which language the shader is written in. + if (_language == SL_none) { + string header; + parse_init(); + parse_line(header, true, true); + if (header == "//Cg") { + _language = SL_Cg; + } else { + shader_cat.error() + << "Unable to determine shader language of " << sbody._shared << "\n"; + return false; + } + } else if (_language == SL_GLSL) { + shader_cat.error() + << "GLSL shaders must have separate shader bodies!\n"; + return false; + } + + // Determine which language the shader is written in. + if (_language == SL_Cg) { +#ifdef HAVE_CG + cg_get_profile_from_header(_default_caps); + + if (!cg_analyze_shader(_default_caps)) { + shader_cat.error() + << "Shader encountered an error.\n"; + return false; + } +#else + shader_cat.error() + << "Tried to load Cg shader, but no Cg support is enabled.\n"; +#endif + } else { + shader_cat.error() + << "Shader is not in a supported shader-language.\n"; + return false; + } + } + + _loaded = true; + return true; +} + /** * Reads the shader file from the given path into the given string. * @@ -2476,37 +2566,85 @@ read(const ShaderFile &sfile, BamCacheRecord *record) { */ bool Shader:: do_read_source(string &into, const Filename &fn, BamCacheRecord *record) { + VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); + PT(VirtualFile) vf = vfs->find_file(fn, get_model_path()); + if (vf == nullptr) { + shader_cat.error() + << "Could not find shader file: " << fn << "\n"; + return false; + } + if (_language == SL_GLSL && glsl_preprocess) { - // Preprocess the GLSL file as we read it. - std::set open_files; - ostringstream sstr; - if (!r_preprocess_source(sstr, fn, Filename(), open_files, record)) { + istream *source = vf->open_read_file(true); + if (source == nullptr) { + shader_cat.error() + << "Could not open shader file: " << fn << "\n"; return false; } + + // Preprocess the GLSL file as we read it. + shader_cat.info() + << "Preprocessing shader file: " << fn << "\n"; + + std::set open_files; + ostringstream sstr; + if (!r_preprocess_source(sstr, *source, fn, vf->get_filename(), open_files, record)) { + vf->close_read_file(source); + return false; + } + vf->close_read_file(source); into = sstr.str(); } else { shader_cat.info() << "Reading shader file: " << fn << "\n"; - VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); - PT(VirtualFile) vf = vfs->find_file(fn, get_model_path()); - if (vf == nullptr) { - shader_cat.error() - << "Could not find shader file: " << fn << "\n"; - return false; - } - if (!vf->read_file(into, true)) { shader_cat.error() << "Could not read shader file: " << fn << "\n"; return false; } + } - if (record != nullptr) { - record->add_dependent_file(vf); + if (record != nullptr) { + record->add_dependent_file(vf); + } + + _last_modified = std::max(_last_modified, vf->get_timestamp()); + _source_files.push_back(vf->get_filename()); + + // Strip trailing whitespace. + while (!into.empty() && isspace(into[into.size() - 1])) { + into.resize(into.size() - 1); + } + + // Except add back a newline at the end, which is needed by Intel drivers. + into += "\n"; + + return true; +} + +/** + * Loads the shader file from the given string into the given string, + * performing any pre-processing on it that may be necessary. + * + * Returns false if there was an error with this shader bad enough to consider + * it 'invalid'. + */ +bool Shader:: +do_load_source(string &into, const std::string &source, BamCacheRecord *record) { + if (_language == SL_GLSL && glsl_preprocess) { + // Preprocess the GLSL file as we read it. + std::set open_files; + std::ostringstream sstr; + std::istringstream in(source); + if (!r_preprocess_source(sstr, in, Filename("created-shader"), Filename(), + open_files, record)) { + return false; } - _last_modified = std::max(_last_modified, vf->get_timestamp()); - _source_files.push_back(vf->get_filename()); + into = sstr.str(); + + } else { + into = source; } // Strip trailing whitespace. @@ -2528,10 +2666,10 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) { * recursive includes. */ bool Shader:: -r_preprocess_source(ostream &out, const Filename &fn, - const Filename &source_dir, - std::set &once_files, - BamCacheRecord *record, int depth) { +r_preprocess_include(ostream &out, const Filename &fn, + const Filename &source_dir, + std::set &once_files, + BamCacheRecord *record, int depth) { if (depth > glsl_include_recursion_limit) { shader_cat.error() @@ -2549,7 +2687,7 @@ r_preprocess_source(ostream &out, const Filename &fn, PT(VirtualFile) vf = vfs->find_file(fn, path); if (vf == nullptr) { shader_cat.error() - << "Could not find shader file: " << fn << "\n"; + << "Could not find shader include: " << fn << "\n"; return false; } @@ -2562,7 +2700,7 @@ r_preprocess_source(ostream &out, const Filename &fn, istream *source = vf->open_read_file(true); if (source == nullptr) { shader_cat.error() - << "Could not open shader file: " << fn << "\n"; + << "Could not open shader include: " << fn << "\n"; return false; } @@ -2578,30 +2716,43 @@ r_preprocess_source(ostream &out, const Filename &fn, // than that, unfortunately. Don't do this for the top-level file, though. // We don't want anything to get in before a potential #version directive. int fileno = 0; - if (depth > 0) { - fileno = 2048 + _included_files.size(); - // Write it into the vector so that we can substitute it later when we are - // parsing the GLSL error log. Don't store the full filename because it - // would just be too long to display. - _included_files.push_back(fn); + fileno = 2048 + _included_files.size(); - out << "#line 1 " << fileno << " // " << fn << "\n"; - if (shader_cat.is_debug()) { - shader_cat.debug() - << "Preprocessing shader include " << fileno << ": " << fn << "\n"; - } - } else { - shader_cat.info() - << "Preprocessing shader file: " << fn << "\n"; + // Write it into the vector so that we can substitute it later when we are + // parsing the GLSL error log. Don't store the full filename because it + // would just be too long to display. + _included_files.push_back(fn); + + out << "#line 1 " << fileno << " // " << fn << "\n"; + if (shader_cat.is_debug()) { + shader_cat.debug() + << "Preprocessing shader include " << fileno << ": " << fn << "\n"; } + bool result = r_preprocess_source(out, *source, fn, full_fn, once_files, record, fileno, depth); + vf->close_read_file(source); + return result; +} + +/** + * Loads a given GLSL stream line by line, processing any #pragma include and + * once statements, as well as removing any comments. + * + * The set keeps track of which files we have already included, for checking + * recursive includes. + */ +bool Shader:: +r_preprocess_source(ostream &out, istream &in, const Filename &fn, + const Filename &full_fn, std::set &once_files, + BamCacheRecord *record, int fileno, int depth) { + // Iterate over the lines for things we may need to preprocess. string line; int ext_google_include = 0; // 1 = warn, 2 = enable int ext_google_line = 0; bool had_include = false; int lineno = 0; - while (std::getline(*source, line)) { + while (std::getline(in, line)) { ++lineno; if (line.empty()) { @@ -2615,7 +2766,7 @@ r_preprocess_source(ostream &out, const Filename &fn, line.resize(line.size() - 1); string line2; - if (std::getline(*source, line2)) { + if (std::getline(in, line2)) { line += line2; out.put('\n'); ++lineno; @@ -2644,7 +2795,7 @@ r_preprocess_source(ostream &out, const Filename &fn, size_t block_end = line2.find("*/"); while (block_end == string::npos) { // Didn't find it - look in the next line. - if (std::getline(*source, line2)) { + if (std::getline(in, line2)) { out.put('\n'); ++lineno; block_end = line2.find("*/"); @@ -2703,7 +2854,7 @@ r_preprocess_source(ostream &out, const Filename &fn, } // OK, great. Process the include. - if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) { + if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) { // An error occurred. Pass on the failure. shader_cat.error(false) << "included at line " << lineno << " of file " << fn << ":\n " << line << "\n"; @@ -2724,8 +2875,19 @@ r_preprocess_source(ostream &out, const Filename &fn, return false; } - once_files.insert(full_fn); + if (fileno == 0) { + shader_cat.warning() + << "#pragma once in main file at line " + << lineno << " of file " << fn +#ifndef NDEBUG + << ":\n " << line +#endif + << "\n"; + } + if (!full_fn.empty()) { + once_files.insert(full_fn); + } } else { // Forward it, the driver will ignore it if it doesn't know it. out << line << "\n"; @@ -2821,7 +2983,7 @@ r_preprocess_source(ostream &out, const Filename &fn, // OK, great. Process the include. Filename source_dir = full_fn.get_dirname(); - if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) { + if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) { // An error occurred. Pass on the failure. shader_cat.error(false) << "included at line " << lineno << " of file " << fn << ":\n " << line << "\n"; @@ -2865,7 +3027,6 @@ r_preprocess_source(ostream &out, const Filename &fn, } } - vf->close_read_file(source); return true; } @@ -3227,28 +3388,26 @@ make(string body, ShaderLanguage lang) { if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); - shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); - -#ifdef HAVE_CG - if (lang == SL_Cg) { - shader->cg_get_profile_from_header(_default_caps); - - if (!shader->cg_analyze_shader(_default_caps)) { - shader_cat.error() - << "Shader encountered an error.\n"; - return nullptr; - } + if (!shader->load(sbody)) { + return nullptr; } -#endif if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } if (dump_generated_shaders) { @@ -3290,26 +3449,27 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry, if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); - -#ifdef HAVE_CG - if (lang == SL_Cg) { - if (!shader->cg_analyze_shader(_default_caps)) { - shader_cat.error() - << "Shader encountered an error.\n"; - return nullptr; - } + if (!shader->load(sbody)) { + return nullptr; } -#endif if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } return shader; @@ -3333,16 +3493,27 @@ make_compute(ShaderLanguage lang, string body) { if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); + if (!shader->load(sbody)) { + return nullptr; + } if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } return shader; diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 67906210f6..35971b243b 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -616,11 +616,18 @@ private: Shader(ShaderLanguage lang); bool read(const ShaderFile &sfile, BamCacheRecord *record = nullptr); + bool load(const ShaderFile &sbody, BamCacheRecord *record = nullptr); bool do_read_source(std::string &into, const Filename &fn, BamCacheRecord *record); - bool r_preprocess_source(std::ostream &out, const Filename &fn, - const Filename &source_dir, + bool do_load_source(std::string &into, const std::string &source, BamCacheRecord *record); + bool r_preprocess_include(std::ostream &out, const Filename &fn, + const Filename &source_dir, + std::set &open_files, + BamCacheRecord *record, int depth); + bool r_preprocess_source(std::ostream &out, std::istream &in, + const Filename &fn, const Filename &full_fn, std::set &open_files, - BamCacheRecord *record, int depth = 0); + BamCacheRecord *record, + int fileno = 0, int depth = 0); bool check_modified() const; From be464b61b3c10053be3ae65f1dfd0dedacb3429a Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 22:02:45 +0100 Subject: [PATCH 12/15] shader: do not require whitespace around : in #extension directive --- panda/src/gobj/shader.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 4c79745e85..9a4153a5e3 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -2905,7 +2905,7 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, // Check for special preprocessing extensions. char extension[256]; char behavior[9]; - if (sscanf(line.c_str(), " # extension%*[ \t]%255s%*[ \t]:%*[ \t]%8s", extension, behavior) == 2) { + if (sscanf(line.c_str(), " # extension%*[ \t]%255[^: \t] : %8s", extension, behavior) == 2) { // Parse the behavior string. int mode; if (strcmp(behavior, "require") == 0 || strcmp(behavior, "enable") == 0) { From f4a8e923f7c08cd9d398a6081c295c721c41720b Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 22:03:10 +0100 Subject: [PATCH 13/15] dxgsg9: fix startup freeze when VRAM is 4GiB or higher --- panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index ce8d33165f..8cb8b9782f 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -341,11 +341,13 @@ find_all_card_memavails() { if (!ISPOW2(dwVidMemTotal)) { // assume they wont return a proper max value, so round up to next pow // of 2 - UINT count = 0; - while ((dwVidMemTotal >> count) != 0x0) { - count++; + int count = get_next_higher_bit((uint32_t)(dwVidMemTotal - 1u)); + if (count >= 32u) { + // Maximum value that fits in a UINT. + dwVidMemTotal = 0xffffffffu; + } else { + dwVidMemTotal = (1u << count); } - dwVidMemTotal = (1 << count); } } From c4f5ed308f1bd621916fea223719f7ea961aaf0b Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 23:25:17 +0100 Subject: [PATCH 14/15] shader: reduce unnecessary newlines and #line in preprocessed GLSL This is done by only writing out a #line when the first non-whitespace line is encountered; any blank lines before that are trimmed. This cuts down the size of the preprocessed shaders for a large project with many shader includes, such as the RenderPipeline. --- panda/src/gobj/shader.cxx | 66 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 9a4153a5e3..4b635b00e7 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -2723,7 +2723,6 @@ r_preprocess_include(ostream &out, const Filename &fn, // would just be too long to display. _included_files.push_back(fn); - out << "#line 1 " << fileno << " // " << fn << "\n"; if (shader_cat.is_debug()) { shader_cat.debug() << "Preprocessing shader include " << fileno << ": " << fn << "\n"; @@ -2752,11 +2751,17 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, int ext_google_line = 0; bool had_include = false; int lineno = 0; + bool write_line_directive = (fileno != 0); + while (std::getline(in, line)) { ++lineno; if (line.empty()) { - out.put('\n'); + // We still write a newline to make sure the line numbering remains + // consistent, unless we are about to write a #line directive anyway. + if (!write_line_directive) { + out.put('\n'); + } continue; } @@ -2768,7 +2773,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, if (std::getline(in, line2)) { line += line2; - out.put('\n'); + if (!write_line_directive) { + out.put('\n'); + } ++lineno; } else { break; @@ -2796,7 +2803,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, while (block_end == string::npos) { // Didn't find it - look in the next line. if (std::getline(in, line2)) { - out.put('\n'); + if (!write_line_directive) { + out.put('\n'); + } ++lineno; block_end = line2.find("*/"); } else { @@ -2814,10 +2823,21 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, line.resize(line.size() - 1); } + if (line.empty()) { + if (!write_line_directive) { + out.put('\n'); + } + continue; + } + // Check if this line contains a #directive. char directive[64]; if (line.size() < 8 || sscanf(line.c_str(), " # %63s", directive) != 1) { // Nope. Just pass the line through unmodified. + if (write_line_directive) { + out << "#line " << lineno << " " << fileno << " // " << fn << "\n"; + write_line_directive = false; + } out << line << "\n"; continue; } @@ -2862,8 +2882,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, } // Restore the line counter. - out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n"; + write_line_directive = true; had_include = true; + continue; } else if (strcmp(pragma, "once") == 0) { // Do a stricter syntax check, just to be extra safe. @@ -2888,17 +2909,15 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, if (!full_fn.empty()) { once_files.insert(full_fn); } - } else { - // Forward it, the driver will ignore it if it doesn't know it. - out << line << "\n"; + continue; } + // Otherwise, just pass it through to the driver. } else if (strcmp(directive, "endif") == 0) { // Check for an #endif after an include. We have to restore the line // number in case the include happened under an #if block. - out << line << "\n"; if (had_include) { - out << "#line " << (lineno + 1) << " " << fileno << "\n"; + write_line_directive = true; } } else if (strcmp(directive, "extension") == 0) { @@ -2931,7 +2950,8 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, } ext_google_include = mode; ext_google_line = mode; - out << line << "\n"; + // Still pass it through to the driver, so it can enable other + // extensions. } else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) { // Enable the Google extension support for #include statements. @@ -2939,14 +2959,12 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, // This matches the behavior of Khronos' glslang reference compiler. ext_google_include = mode; ext_google_line = mode; + continue; } else if (strcmp(extension, "GL_GOOGLE_cpp_style_line_directive") == 0) { // Enables strings in #line statements. ext_google_line = mode; - - } else { - // It's an extension the driver should worry about. - out << line << "\n"; + continue; } } else { shader_cat.error() @@ -2954,6 +2972,7 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, << lineno << " of file " << fn << ":\n " << line << "\n"; return false; } + } else if (ext_google_include > 0 && strcmp(directive, "include") == 0) { // Warn about extension use if requested. if (ext_google_include == 1) { @@ -2991,8 +3010,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, } // Restore the line counter. - out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n"; + write_line_directive = true; had_include = true; + continue; } else if (ext_google_line > 0 && strcmp(directive, "line") == 0) { // It's a #line directive. See if it uses a string instead of number. @@ -3016,15 +3036,15 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, _included_files.push_back(Filename(filestr)); out << "#line " << lineno << " " << fileno << " // " << filestr << "\n"; - - } else { - // We couldn't parse the #line directive. Pass it through unmodified. - out << line << "\n"; + continue; } - } else { - // Different directive (eg. #version). Leave it untouched. - out << line << "\n"; } + + if (write_line_directive) { + out << "#line " << lineno << " " << fileno << " // " << fn << "\n"; + write_line_directive = false; + } + out << line << "\n"; } return true; From a246acc64046fd6d4f0582b749f192710bd48c39 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Thu, 1 Nov 2018 16:03:58 -0600 Subject: [PATCH 15/15] windisplay: Undefine Configure before including d3d9.h This is for consistency with fbbc5bb9e63 which introduced the same `#undef Configure` in dxgsg9. This prevents dtool's own Configure() macro from conflicting with the declaration of D3D9's Configure function in d3d9.h. --- panda/src/windisplay/winDetectDx9.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/panda/src/windisplay/winDetectDx9.cxx b/panda/src/windisplay/winDetectDx9.cxx index 2e293950f6..4be10f0492 100644 --- a/panda/src/windisplay/winDetectDx9.cxx +++ b/panda/src/windisplay/winDetectDx9.cxx @@ -18,6 +18,7 @@ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif +#undef Configure #include #include "graphicsStateGuardian.h" #include "graphicsPipe.h"