diff --git a/CMakeLists.txt b/CMakeLists.txt index 793897f02..2c3dd7dca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ file (GLOB CXBXR_HEADER_EMU "${CXBXR_ROOT_DIR}/src/common/XADPCM.h" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Direct3D9.h" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShader.h" + "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShaderSource.h" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/WalkIndexBuffer.h" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/ResourceTracker.h" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbConvert.h" @@ -266,6 +267,7 @@ file (GLOB CXBXR_SOURCE_EMU "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/RenderStates.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/TextureStates.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShader.cpp" + "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShaderSource.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/WalkIndexBuffer.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/ResourceTracker.cpp" "${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbConvert.cpp" diff --git a/resource/Cxbx.rc b/resource/Cxbx.rc index 614d33f54..8cc6d1518 100644 --- a/resource/Cxbx.rc +++ b/resource/Cxbx.rc @@ -13,11 +13,11 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// Language neutral resources +// Neutral resources -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(65001) +#pragma code_page(1252) ///////////////////////////////////////////////////////////////////////////// // @@ -88,90 +88,90 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMEN CAPTION "Cxbx-Reloaded : Input Configuration" FONT 8, "Verdana", 0, 0, 0x1 BEGIN - GROUPBOX "Xbox device configuration", IDC_XID_CONFIG, 13, 10, 217, 103, WS_GROUP, WS_EX_CLIENTEDGE - COMBOBOX IDC_DEVICE_PORT1, 50, 25, 110, 14, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_DEVICE_PORT2, 50, 46, 110, 14, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_DEVICE_PORT3, 50, 67, 110, 14, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_DEVICE_PORT4, 50, 88, 110, 14, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure", IDC_CONFIGURE_PORT1, 166, 25, 50, 14, BS_FLAT - PUSHBUTTON "Configure", IDC_CONFIGURE_PORT2, 166, 46, 50, 14, BS_FLAT - PUSHBUTTON "Configure", IDC_CONFIGURE_PORT3, 166, 67, 50, 14, BS_FLAT - PUSHBUTTON "Configure", IDC_CONFIGURE_PORT4, 166, 88, 50, 14, BS_FLAT - LTEXT "Port 1", IDC_STATIC, 23, 27, 20, 10 - LTEXT "Port 2", IDC_STATIC, 23, 48, 20, 10 - LTEXT "Port 3", IDC_STATIC, 23, 69, 20, 10 - LTEXT "Port 4", IDC_STATIC, 23, 90, 20, 10 + GROUPBOX "Xbox device configuration",IDC_XID_CONFIG,13,10,217,103,WS_GROUP,WS_EX_CLIENTEDGE + COMBOBOX IDC_DEVICE_PORT1,50,25,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DEVICE_PORT2,50,46,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DEVICE_PORT3,50,67,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DEVICE_PORT4,50,88,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURE_PORT1,166,25,50,14,BS_FLAT + PUSHBUTTON "Configure",IDC_CONFIGURE_PORT2,166,46,50,14,BS_FLAT + PUSHBUTTON "Configure",IDC_CONFIGURE_PORT3,166,67,50,14,BS_FLAT + PUSHBUTTON "Configure",IDC_CONFIGURE_PORT4,166,88,50,14,BS_FLAT + LTEXT "Port 1",IDC_STATIC,23,27,20,10 + LTEXT "Port 2",IDC_STATIC,23,48,20,10 + LTEXT "Port 3",IDC_STATIC,23,69,20,10 + LTEXT "Port 4",IDC_STATIC,23,90,20,10 END IDD_XID_DUKE_CFG DIALOGEX 0, 0, 528, 280 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU FONT 8, "Verdana", 0, 0, 0x1 BEGIN - GROUPBOX "Device", IDC_XID_CONFIG, 12, 10, 175, 35, WS_GROUP - COMBOBOX IDC_DEVICE_LIST, 21, 23, 101, 15, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Refresh", IDC_REFRESH_DEVICES, 128, 23, 50, 14, BS_FLAT - GROUPBOX "Profile", IDC_XID_PROFILE, 197, 10, 320, 35, WS_GROUP - COMBOBOX IDC_XID_PROFILE_NAME, 207, 24, 194, 10, CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Save", IDC_XID_PROFILE_SAVE, 405, 23, 50, 14, BS_FLAT - PUSHBUTTON "Delete", IDC_XID_PROFILE_DELETE, 459, 23, 50, 14, BS_FLAT - GROUPBOX "Buttons", IDC_XID_BUTTONS, 12, 65, 121, 181, WS_GROUP - PUSHBUTTON "", IDC_SET_A, 59, 75, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_B, 59, 93, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_X, 59, 111, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_Y, 59, 129, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_BLACK, 59, 147, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_WHITE, 59, 165, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_BACK, 59, 183, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_START, 59, 201, 57, 14, BS_FLAT - LTEXT "A", IDC_STATIC, 28, 75, 20, 14, SS_CENTERIMAGE - LTEXT "B", IDC_STATIC, 28, 93, 20, 14, SS_CENTERIMAGE - LTEXT "X", IDC_STATIC, 28, 111, 20, 14, SS_CENTERIMAGE - LTEXT "Y", IDC_STATIC, 28, 129, 20, 14, SS_CENTERIMAGE - LTEXT "Black", IDC_STATIC, 28, 147, 20, 14, SS_CENTERIMAGE - LTEXT "White", IDC_STATIC, 28, 165, 20, 14, SS_CENTERIMAGE - LTEXT "Back", IDC_STATIC, 28, 183, 20, 14, SS_CENTERIMAGE - LTEXT "Start", IDC_STATIC, 28, 201, 20, 14, SS_CENTERIMAGE - GROUPBOX "L Stick", IDC_XID_LSTICK, 140, 65, 121, 181, WS_GROUP - PUSHBUTTON "", IDC_SET_LEFT_POSY, 187, 75, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_LEFT_NEGY, 187, 93, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_LEFT_NEGX, 187, 111, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_LEFT_POSX, 187, 129, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_LTHUMB, 187, 147, 57, 14, BS_FLAT - LTEXT "Up", IDC_STATIC, 156, 75, 20, 14, SS_CENTERIMAGE - LTEXT "Down", IDC_STATIC, 156, 93, 20, 14, SS_CENTERIMAGE - LTEXT "Left", IDC_STATIC, 156, 111, 20, 14, SS_CENTERIMAGE - LTEXT "Right", IDC_STATIC, 156, 129, 20, 14, SS_CENTERIMAGE - LTEXT "L Click", IDC_STATIC, 156, 147, 27, 14, SS_CENTERIMAGE - GROUPBOX "R Stick", IDC_XID_RSTICK, 268, 65, 121, 181, WS_GROUP - PUSHBUTTON "", IDC_SET_RIGHT_POSY, 315, 75, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_RIGHT_NEGY, 315, 93, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_RIGHT_NEGX, 315, 111, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_RIGHT_POSX, 315, 129, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_RTHUMB, 315, 147, 57, 14, BS_FLAT - LTEXT "Up", IDC_STATIC, 284, 75, 20, 14, SS_CENTERIMAGE - LTEXT "Down", IDC_STATIC, 284, 93, 20, 14, SS_CENTERIMAGE - LTEXT "Left", IDC_STATIC, 284, 111, 20, 14, SS_CENTERIMAGE - LTEXT "Right", IDC_STATIC, 284, 129, 20, 14, SS_CENTERIMAGE - LTEXT "R Click", IDC_STATIC, 284, 147, 27, 14, SS_CENTERIMAGE - GROUPBOX "D Pad", IDC_XID_DPAD, 396, 65, 121, 88, WS_GROUP - PUSHBUTTON "", IDC_SET_DPAD_UP, 443, 75, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_DPAD_DOWN, 443, 93, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_DPAD_LEFT, 443, 111, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_DPAD_RIGHT, 443, 129, 57, 14, BS_FLAT - LTEXT "Up", IDC_STATIC, 412, 75, 20, 14, SS_CENTERIMAGE - LTEXT "Down", IDC_STATIC, 412, 93, 20, 14, SS_CENTERIMAGE - LTEXT "Left", IDC_STATIC, 412, 111, 20, 14, SS_CENTERIMAGE - LTEXT "Right", IDC_STATIC, 412, 129, 20, 14, SS_CENTERIMAGE - GROUPBOX "Triggers", IDC_XID_TRIGGERS, 396, 157, 121, 52, WS_GROUP - PUSHBUTTON "", IDC_SET_LTRIGGER, 443, 168, 57, 14, BS_FLAT - PUSHBUTTON "", IDC_SET_RTRIGGER, 443, 187, 57, 14, BS_FLAT - LTEXT "Left", IDC_STATIC, 412, 168, 20, 14, SS_CENTERIMAGE - LTEXT "Right", IDC_STATIC, 412, 187, 20, 14, SS_CENTERIMAGE - GROUPBOX "Rumble", IDC_XID_RUMBLE, 396, 212, 121, 34, WS_GROUP - PUSHBUTTON "", IDC_SET_MOTOR, 443, 224, 57, 14, BS_FLAT - LTEXT "Motor", IDC_STATIC, 412, 224, 26, 14, SS_CENTERIMAGE - PUSHBUTTON "Default Bindings", IDC_XID_DEFAULT, 362, 256, 69, 14, BS_FLAT - PUSHBUTTON "Clear", IDC_XID_CLEAR, 443, 256, 50, 14, BS_FLAT + GROUPBOX "Device",IDC_XID_CONFIG,12,10,175,35,WS_GROUP + COMBOBOX IDC_DEVICE_LIST,21,23,101,15,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Refresh",IDC_REFRESH_DEVICES,128,23,50,14,BS_FLAT + GROUPBOX "Profile",IDC_XID_PROFILE,197,10,320,35,WS_GROUP + COMBOBOX IDC_XID_PROFILE_NAME,207,24,194,10,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Save",IDC_XID_PROFILE_SAVE,405,23,50,14,BS_FLAT + PUSHBUTTON "Delete",IDC_XID_PROFILE_DELETE,459,23,50,14,BS_FLAT + GROUPBOX "Buttons",IDC_XID_BUTTONS,12,65,121,181,WS_GROUP + PUSHBUTTON "",IDC_SET_A,59,75,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_B,59,93,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_X,59,111,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_Y,59,129,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_BLACK,59,147,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_WHITE,59,165,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_BACK,59,183,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_START,59,201,57,14,BS_FLAT + LTEXT "A",IDC_STATIC,28,75,20,14,SS_CENTERIMAGE + LTEXT "B",IDC_STATIC,28,93,20,14,SS_CENTERIMAGE + LTEXT "X",IDC_STATIC,28,111,20,14,SS_CENTERIMAGE + LTEXT "Y",IDC_STATIC,28,129,20,14,SS_CENTERIMAGE + LTEXT "Black",IDC_STATIC,28,147,20,14,SS_CENTERIMAGE + LTEXT "White",IDC_STATIC,28,165,20,14,SS_CENTERIMAGE + LTEXT "Back",IDC_STATIC,28,183,20,14,SS_CENTERIMAGE + LTEXT "Start",IDC_STATIC,28,201,20,14,SS_CENTERIMAGE + GROUPBOX "L Stick",IDC_XID_LSTICK,140,65,121,181,WS_GROUP + PUSHBUTTON "",IDC_SET_LEFT_POSY,187,75,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_LEFT_NEGY,187,93,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_LEFT_NEGX,187,111,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_LEFT_POSX,187,129,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_LTHUMB,187,147,57,14,BS_FLAT + LTEXT "Up",IDC_STATIC,156,75,20,14,SS_CENTERIMAGE + LTEXT "Down",IDC_STATIC,156,93,20,14,SS_CENTERIMAGE + LTEXT "Left",IDC_STATIC,156,111,20,14,SS_CENTERIMAGE + LTEXT "Right",IDC_STATIC,156,129,20,14,SS_CENTERIMAGE + LTEXT "L Click",IDC_STATIC,156,147,27,14,SS_CENTERIMAGE + GROUPBOX "R Stick",IDC_XID_RSTICK,268,65,121,181,WS_GROUP + PUSHBUTTON "",IDC_SET_RIGHT_POSY,315,75,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_RIGHT_NEGY,315,93,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_RIGHT_NEGX,315,111,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_RIGHT_POSX,315,129,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_RTHUMB,315,147,57,14,BS_FLAT + LTEXT "Up",IDC_STATIC,284,75,20,14,SS_CENTERIMAGE + LTEXT "Down",IDC_STATIC,284,93,20,14,SS_CENTERIMAGE + LTEXT "Left",IDC_STATIC,284,111,20,14,SS_CENTERIMAGE + LTEXT "Right",IDC_STATIC,284,129,20,14,SS_CENTERIMAGE + LTEXT "R Click",IDC_STATIC,284,147,27,14,SS_CENTERIMAGE + GROUPBOX "D Pad",IDC_XID_DPAD,396,65,121,88,WS_GROUP + PUSHBUTTON "",IDC_SET_DPAD_UP,443,75,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_DPAD_DOWN,443,93,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_DPAD_LEFT,443,111,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_DPAD_RIGHT,443,129,57,14,BS_FLAT + LTEXT "Up",IDC_STATIC,412,75,20,14,SS_CENTERIMAGE + LTEXT "Down",IDC_STATIC,412,93,20,14,SS_CENTERIMAGE + LTEXT "Left",IDC_STATIC,412,111,20,14,SS_CENTERIMAGE + LTEXT "Right",IDC_STATIC,412,129,20,14,SS_CENTERIMAGE + GROUPBOX "Triggers",IDC_XID_TRIGGERS,396,157,121,52,WS_GROUP + PUSHBUTTON "",IDC_SET_LTRIGGER,443,168,57,14,BS_FLAT + PUSHBUTTON "",IDC_SET_RTRIGGER,443,187,57,14,BS_FLAT + LTEXT "Left",IDC_STATIC,412,168,20,14,SS_CENTERIMAGE + LTEXT "Right",IDC_STATIC,412,187,20,14,SS_CENTERIMAGE + GROUPBOX "Rumble",IDC_XID_RUMBLE,396,212,121,34,WS_GROUP + PUSHBUTTON "",IDC_SET_MOTOR,443,224,57,14,BS_FLAT + LTEXT "Motor",IDC_STATIC,412,224,26,14,SS_CENTERIMAGE + PUSHBUTTON "Default Bindings",IDC_XID_DEFAULT,362,256,69,14,BS_FLAT + PUSHBUTTON "Clear",IDC_XID_CLEAR,443,256,50,14,BS_FLAT END IDD_RUMBLE_CFG DIALOGEX 0, 0, 155, 35 @@ -179,8 +179,8 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMEN CAPTION "Rumble Configuration" FONT 8, "Verdana", 0, 0, 0x1 BEGIN - COMBOBOX IDC_RUMBLE_LIST, 15, 11, 70, 15, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Test", IDC_RUMBLE_TEST, 95, 11, 45, 14, BS_FLAT + COMBOBOX IDC_RUMBLE_LIST,15,11,70,15,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Test",IDC_RUMBLE_TEST,95,11,45,14,BS_FLAT END IDD_VIRTUAL_SBC_FEEDBACK DIALOGEX 0, 0, 1039, 214 @@ -431,23 +431,23 @@ BEGIN CONTROL "PSHB",IDC_LOG_PSHB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,144,126,34,10 CONTROL "PXSH",IDC_LOG_PXSH,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,200,126,34,10 CONTROL "VTXSH",IDC_LOG_VTXSH,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,28,140,38,10 - CONTROL "VTXB",IDC_LOG_VTXB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,87,140,34,10 - CONTROL "DINP",IDC_LOG_DINP,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,145,140,33,10 - CONTROL "XINP",IDC_LOG_XINP,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,202,140,32,10 - CONTROL "SDL",IDC_LOG_SDL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,33,155,33,10 - CONTROL "FILE",IDC_LOG_FILE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,91,155,30,10 - CONTROL "X86",IDC_LOG_X86,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,149,155,29,10 - CONTROL "HLE",IDC_LOG_HLE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,206,155,28,10 - CONTROL "NET",IDC_LOG_NET,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,37,168,29,10 - CONTROL "MCPX",IDC_LOG_MCPX,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,86,168,35,10 - CONTROL "NV2A",IDC_LOG_NV2A,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,144,168,34,10 - CONTROL "SMC",IDC_LOG_SMC,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,203,168,31,10 - CONTROL "OHCI",IDC_LOG_OHCI,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,32,182,34,10 - CONTROL "USB",IDC_LOG_USB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,91,182,30,10 - CONTROL "HUB",IDC_LOG_HUB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,148,182,30,10 - CONTROL "XIDCTRL",IDC_LOG_XIDCTRL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,188,182,46,10 - CONTROL "ADM",IDC_LOG_ADM,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,35,195,31,10 - CONTROL "INPSYS",IDC_LOG_INPSYS,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,80,195,41,10 + CONTROL "VTXB",IDC_LOG_VTXB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,144,140,34,10 + CONTROL "DINP",IDC_LOG_DINP,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,201,140,33,10 + CONTROL "XINP",IDC_LOG_XINP,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,34,155,32,10 + CONTROL "SDL",IDC_LOG_SDL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,88,155,33,10 + CONTROL "FILE",IDC_LOG_FILE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,148,155,30,10 + CONTROL "X86",IDC_LOG_X86,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,205,155,29,10 + CONTROL "HLE",IDC_LOG_HLE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,38,168,28,10 + CONTROL "NET",IDC_LOG_NET,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,92,168,29,10 + CONTROL "MCPX",IDC_LOG_MCPX,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,143,168,35,10 + CONTROL "NV2A",IDC_LOG_NV2A,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,200,168,34,10 + CONTROL "SMC",IDC_LOG_SMC,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,35,182,31,10 + CONTROL "OHCI",IDC_LOG_OHCI,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,87,182,34,10 + CONTROL "USB",IDC_LOG_USB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,148,182,30,10 + CONTROL "HUB",IDC_LOG_HUB,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,204,182,30,10 + CONTROL "XIDCTRL",IDC_LOG_XIDCTRL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,20,195,46,10 + CONTROL "ADM",IDC_LOG_ADM,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,90,195,31,10 + CONTROL "INPSYS",IDC_LOG_INPSYS,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,137,195,41,10 GROUPBOX "Kernel Event",IDC_KERNEL_EVENTS,12,218,234,110,WS_GROUP,WS_EX_CLIENTEDGE CONTROL "Enable all",IDC_LOG_ENABLE_KERNEL,"Button",BS_AUTORADIOBUTTON | BS_LEFTTEXT,19,232,47,10 CONTROL "Disable all",IDC_LOG_DISABLE_KERNEL,"Button",BS_AUTORADIOBUTTON | BS_LEFTTEXT,71,232,50,10 @@ -474,6 +474,15 @@ BEGIN CONTROL "XE",IDC_LOG_XE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,209,308,25,10 PUSHBUTTON "Cancel",IDC_LOG_CANCEL,161,333,40,14,BS_FLAT PUSHBUTTON "Accept",IDC_LOG_ACCEPT,206,333,40,14,BS_FLAT + CONTROL "VSHCACHE",IDC_LOG_VSHCACHE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,68,140,53,10 +END + +IDD_ABOUT DIALOGEX 0, 0, 310, 177 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Cxbx-Reloaded" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_TAB1,"SysTabControl32",0x0,7,7,296,163 END @@ -517,6 +526,11 @@ BEGIN 0 END +IDD_ABOUT AFX_DIALOG_LAYOUT +BEGIN + 0 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -629,7 +643,7 @@ BEGIN END POPUP "&Settings", 65535,MFT_STRING,MFS_ENABLED BEGIN - MENUITEM "Config I&nput...", ID_SETTINGS_CONFIG_INPUT, MFT_STRING, MFS_ENABLED + MENUITEM "Config I&nput...", ID_SETTINGS_CONFIG_INPUT,MFT_STRING,MFS_ENABLED MENUITEM "Config &Video...", ID_SETTINGS_CONFIG_VIDEO,MFT_STRING,MFS_ENABLED MENUITEM "Config &Audio...", ID_SETTINGS_CONFIG_AUDIO,MFT_STRING,MFS_ENABLED MENUITEM "Config &Network...", ID_SETTINGS_CONFIG_NETWORK,MFT_STRING,MFS_ENABLED @@ -649,7 +663,7 @@ BEGIN MENUITEM MFT_SEPARATOR POPUP "&LLE (Experimental)", 65535,MFT_STRING,MFS_ENABLED BEGIN - MENUITEM "LLE &GPU", ID_EMULATION_LLE_GPU,MFT_STRING,MFS_DISABLED + MENUITEM "LLE &GPU", ID_EMULATION_LLE_GPU,MFT_STRING,MFS_GRAYED END POPUP "Hacks", 65535,MFT_STRING,MFS_ENABLED BEGIN @@ -682,30 +696,6 @@ BEGIN MENUITEM " ", ID_LOG,MFT_STRING,MFS_ENABLED END -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUT DIALOGEX 0, 0, 310, 177 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About Cxbx-Reloaded" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,7,7,296,163 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// AFX_DIALOG_LAYOUT -// - -IDD_ABOUT AFX_DIALOG_LAYOUT -BEGIN - 0 -END - ///////////////////////////////////////////////////////////////////////////// // @@ -716,8 +706,7 @@ IDR_CONTRIBUTORS TXT "..\\CONTRIBUTORS" IDR_COPYING TXT "..\\COPYING" -#endif // Language neutral resources - +#endif // Neutral resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/common/Logging.cpp b/src/common/Logging.cpp index fd5649a03..bffc652e2 100644 --- a/src/common/Logging.cpp +++ b/src/common/Logging.cpp @@ -58,6 +58,7 @@ const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)] = { "PSHB ", "PXSH ", "VTXSH ", + "VSHCACHE", "VTXB ", "DINP ", "XINP ", diff --git a/src/common/Logging.h b/src/common/Logging.h index 2b4f5019d..122322e20 100644 --- a/src/common/Logging.h +++ b/src/common/Logging.h @@ -66,6 +66,7 @@ typedef enum class _CXBXR_MODULE: unsigned int { PSHB, PXSH, VTXSH, + VSHCACHE, VTXB, DINP, XINP, diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index ffc0a7309..c7b1dddc5 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -62,7 +62,7 @@ namespace xboxkrnl #include "core\kernel\common\strings.hpp" // For uem_str #include "common\input\SdlJoystick.h" #include "common/util/strConverter.hpp" // for utf8_to_utf16 -#include "VertexShader.h" +#include "VertexShaderSource.h" #include #include @@ -547,19 +547,6 @@ const char *CxbxGetErrorDescription(HRESULT hResult) return nullptr; } -// TODO move to shader file. Needs to be called whenever a shader or declaration is set -void SetVertexRegisterDefaultFlags(CxbxVertexShader* pCxbxVertexShader) { - if (pCxbxVertexShader != nullptr && pCxbxVertexShader->pHostVertexShader != nullptr) { - // Titles can specify default values for registers via calls like SetVertexData4f - // HLSL shaders need to know whether to use vertex data or default vertex shader values - // Any register not in the vertex declaration should be set to the default value - float vertexDefaultFlags[16]; - for (int i = 0; i < 16; i++) { - vertexDefaultFlags[i] = pCxbxVertexShader->VertexShaderInfo.vRegisterInDeclaration[i] ? 0.0f : 1.0f; - } - g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_BASE, vertexDefaultFlags, 4); - } -} const char *D3DErrorString(HRESULT hResult) { @@ -861,6 +848,7 @@ typedef struct { typedef std::unordered_map resource_cache_t; resource_cache_t g_Cxbx_Cached_Direct3DResources; resource_cache_t g_Cxbx_Cached_PaletizedTextures; +VertexShaderSource g_VertexShaderSource = VertexShaderSource(); bool IsResourceAPixelContainer(XTL::DWORD XboxResource_Common) { @@ -988,6 +976,48 @@ IDirect3DResource *GetHostResource(XTL::X_D3DResource *pXboxResource, DWORD D3DU return it->second.pHostResource; } +void SetCxbxVertexShader(CxbxVertexShader* pCxbxVertexShader) { + + LOG_INIT + + HRESULT hRet; + + // Get vertex shader if we have a key + auto pHostShader = pCxbxVertexShader->VertexShaderKey + ? g_VertexShaderSource.GetShader(pCxbxVertexShader->VertexShaderKey) + : nullptr; + + // Set vertex shader + hRet = g_pD3DDevice->SetVertexShader(pHostShader); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader"); + + // Set either FVF or the vertex declaration + if (pCxbxVertexShader->HostFVF) + { + // Set the FVF + hRet = g_pD3DDevice->SetFVF(pCxbxVertexShader->HostFVF); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetFVF"); + } + else + { + // Set vertex declaration + hRet = g_pD3DDevice->SetVertexDeclaration(pCxbxVertexShader->pHostVertexDeclaration); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexDeclaration"); + } + + // Set vertex shader constants if necessary + if (pHostShader) { + // Titles can specify default values for registers via calls like SetVertexData4f + // HLSL shaders need to know whether to use vertex data or default vertex shader values + // Any register not in the vertex declaration should be set to the default value + float vertexDefaultFlags[16]; + for (int i = 0; i < 16; i++) { + vertexDefaultFlags[i] = pCxbxVertexShader->VertexShaderInfo.vRegisterInDeclaration[i] ? 0.0f : 1.0f; + } + g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_BASE, vertexDefaultFlags, 4); + } +} + // Forward declaration of CxbxGetPixelContainerMeasures to prevent // polluting the diff too much by reshuffling functions around VOID CxbxGetPixelContainerMeasures @@ -2568,6 +2598,9 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID) // begin scene hRet = g_pD3DDevice->BeginScene(); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->BeginScene(2nd)"); + + // Set up cache + g_VertexShaderSource.ResetD3DDevice(g_pD3DDevice); } // signal completion @@ -3554,10 +3587,17 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader) if(VshHandleIsVertexShader(Handle)) { pCxbxVertexShader = GetCxbxVertexShader(Handle); + SetCxbxVertexShader(pCxbxVertexShader); } else if(Handle == xbnull) { HostFVF = D3DFVF_XYZ | D3DFVF_TEX0; + // Clear any vertex shader that may be set + hRet = g_pD3DDevice->SetVertexShader(nullptr); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader()"); + // Set the FVF + hRet = g_pD3DDevice->SetFVF(HostFVF); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_TEX0)"); } else if(Address < 136) { @@ -3575,28 +3615,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader) } } - IDirect3DVertexDeclaration* pHostVertexDeclaration = nullptr; - IDirect3DVertexShader* pHostVertexShader = nullptr; - - if (pCxbxVertexShader) - { - pHostVertexDeclaration = pCxbxVertexShader->pHostVertexDeclaration; - pHostVertexShader = pCxbxVertexShader->pHostVertexShader; - HostFVF = pCxbxVertexShader->HostFVF; - - SetVertexRegisterDefaultFlags(pCxbxVertexShader); - } - - hRet = g_pD3DDevice->SetVertexDeclaration(pHostVertexDeclaration); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexDeclaration()"); - hRet = g_pD3DDevice->SetVertexShader(pHostVertexShader); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader()"); - if (HostFVF) // should equal (pHostVertexShader == nullptr) - { - hRet = g_pD3DDevice->SetFVF(HostFVF); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_TEX0)"); - } - if (FAILED(hRet)) { EmuLog(LOG_LEVEL::WARNING, "We're lying about setting a vertext shader!"); @@ -4247,6 +4265,8 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) // Create the vertex declaration hRet = g_pD3DDevice->CreateVertexDeclaration(pRecompiledDeclaration, &pCxbxVertexShader->pHostVertexDeclaration); + free(pRecompiledDeclaration); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexDeclaration"); if (FAILED(hRet)) { @@ -4256,59 +4276,13 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) g_pD3DDevice->SetVertexDeclaration(pCxbxVertexShader->pHostVertexDeclaration); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexDeclaration"); - ID3DBlob *pRecompiledBuffer = nullptr; + uint64_t vertexShaderKey = 0; DWORD XboxFunctionSize = 0; - DWORD *pRecompiledFunction = nullptr; if (SUCCEEDED(hRet) && pFunction) { - auto intermediateShader = IntermediateVertexShader(); - - // TOOD handle parse return value? - hRet = EmuParseVshFunction((DWORD*)pFunction, - &XboxFunctionSize, - &intermediateShader); - - // Try to compile the shader - hRet = EmuCompileShader( - &intermediateShader, - &pRecompiledBuffer - ); - - if (SUCCEEDED(hRet)) - { - if (pRecompiledBuffer) - pRecompiledFunction = (DWORD*)pRecompiledBuffer->GetBufferPointer(); - else - pRecompiledFunction = nullptr; - } - else - { - pRecompiledFunction = nullptr; - EmuLog(LOG_LEVEL::WARNING, "Couldn't recompile vertex shader function."); - } + vertexShaderKey = g_VertexShaderSource.CreateShader(pFunction, &XboxFunctionSize); } - //EmuLog(LOG_LEVEL::DEBUG, "MaxVertexShaderConst = %d", g_D3DCaps.MaxVertexShaderConst); - - IDirect3DVertexShader* pHostVertexShader = nullptr; - if (SUCCEEDED(hRet) && pRecompiledFunction != nullptr) - { - hRet = g_pD3DDevice->CreateVertexShader - ( - pRecompiledFunction, - &pHostVertexShader - ); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader"); - } - - if (pRecompiledBuffer != nullptr) - { - pRecompiledBuffer->Release(); - pRecompiledBuffer = nullptr; - } - - free(pRecompiledDeclaration); - pCxbxVertexShader->pXboxDeclarationCopy = (DWORD*)malloc(XboxDeclarationCount * sizeof(DWORD)); memcpy(pCxbxVertexShader->pXboxDeclarationCopy, pDeclaration, XboxDeclarationCount * sizeof(DWORD)); pCxbxVertexShader->XboxFunctionSize = 0; @@ -4316,7 +4290,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) pCxbxVertexShader->XboxVertexShaderType = X_VST_NORMAL; // TODO : This can vary pCxbxVertexShader->XboxNrAddressSlots = (XboxFunctionSize - sizeof(X_VSH_SHADER_HEADER)) / X_VSH_INSTRUCTION_SIZE_BYTES; pCxbxVertexShader->HostFVF = 0; - pCxbxVertexShader->pHostVertexShader = nullptr; + pCxbxVertexShader->VertexShaderKey = vertexShaderKey; pCxbxVertexShader->XboxDeclarationCount = XboxDeclarationCount; // Save the status, to remove things later // pCxbxVertexShader->XboxStatus = hRet; // Not even used by VshHandleIsValidShader() @@ -4329,8 +4303,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) pCxbxVertexShader->pXboxFunctionCopy = (DWORD*)malloc(XboxFunctionSize); memcpy(pCxbxVertexShader->pXboxFunctionCopy, pFunction, XboxFunctionSize); } - - pCxbxVertexShader->pHostVertexShader = pHostVertexShader; } else { @@ -6804,20 +6776,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader) if (VshHandleIsVertexShader(Handle)) { CxbxVertexShader *pCxbxVertexShader = GetCxbxVertexShader(Handle); - hRet = g_pD3DDevice->SetVertexDeclaration(pCxbxVertexShader->pHostVertexDeclaration); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexDeclaration"); - if (pCxbxVertexShader->HostFVF) - { - hRet = g_pD3DDevice->SetFVF(pCxbxVertexShader->HostFVF); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetFVF(VshHandleIsVertexShader)"); - } - else - { - SetVertexRegisterDefaultFlags(pCxbxVertexShader); - - hRet = g_pD3DDevice->SetVertexShader(pCxbxVertexShader->pHostVertexShader); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)"); - } + SetCxbxVertexShader(pCxbxVertexShader); } else { hRet = g_pD3DDevice->SetVertexShader(nullptr); @@ -8059,10 +8018,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DeleteVertexShader) DEBUG_D3DRESULT(hRet, "g_pD3DDevice->DeleteVertexShader(pHostVertexDeclaration)"); } - if (pCxbxVertexShader->pHostVertexShader) { - HRESULT hRet = pCxbxVertexShader->pHostVertexShader->Release(); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->DeleteVertexShader(pHostVertexShader)"); - } + // Release the host vertex shader + g_VertexShaderSource.ReleaseShader(pCxbxVertexShader->VertexShaderKey); if (pCxbxVertexShader->pXboxDeclarationCopy) { diff --git a/src/core/hle/D3D8/Direct3D9/VertexShader.cpp b/src/core/hle/D3D8/Direct3D9/VertexShader.cpp index 7563908b0..2a58e0a10 100644 --- a/src/core/hle/D3D8/Direct3D9/VertexShader.cpp +++ b/src/core/hle/D3D8/Direct3D9/VertexShader.cpp @@ -192,6 +192,32 @@ std::string DebugPrependLineNumbers(std::string shaderString) { return debugShader.str(); } + +extern ShaderType EmuGetShaderInfo(IntermediateVertexShader* pIntermediateShader) { + + if (pIntermediateShader->Instructions.size() == 0) { + // Do not attempt to compile empty shaders + // This is a declaration only shader, so there is no function to compile + return ShaderType::Empty; + } + + switch (pIntermediateShader->Header.Version) { + case VERSION_XVS: + break; + case VERSION_XVSS: + LOG_TEST_CASE("Might not support vertex state shaders?"); + break; + case VERSION_XVSW: + EmuLog(LOG_LEVEL::WARNING, "Might not support vertex read/write shaders?"); + return ShaderType::Unsupported; + default: + EmuLog(LOG_LEVEL::WARNING, "Unknown vertex shader version 0x%02X", pIntermediateShader->Header.Version); + return ShaderType::Unsupported; + } + + return ShaderType::Compilable; +} + // recompile xbox vertex shader function extern HRESULT EmuCompileShader ( @@ -204,31 +230,6 @@ extern HRESULT EmuCompileShader ID3DBlob* pErrors = nullptr; HRESULT hRet = 0; - switch (pIntermediateShader->Header.Version) { - case VERSION_XVS: - break; - case VERSION_XVSS: - LOG_TEST_CASE("Might not support vertex state shaders?"); - break; - case VERSION_XVSW: - EmuLog(LOG_LEVEL::WARNING, "Might not support vertex read/write shaders?"); - hRet = E_FAIL; - break; - default: - EmuLog(LOG_LEVEL::WARNING, "Unknown vertex shader version 0x%02X", pIntermediateShader->Header.Version); - hRet = E_FAIL; - break; - } - - if (!SUCCEEDED(hRet)) return hRet; - - if (pIntermediateShader->Instructions.size() == 0) { - // Do not attempt to compile empty shaders - // This is a declaration only shader, so there is no function to recompile - ppHostShader = nullptr; - return D3D_OK; - } - // Include HLSL header and footer as raw strings : static std::string hlsl_template[2] = { #include "core\hle\D3D8\Direct3D9\CxbxVertexShaderTemplate.hlsl" diff --git a/src/core/hle/D3D8/Direct3D9/VertexShader.h b/src/core/hle/D3D8/Direct3D9/VertexShader.h index 5e89e77b7..153f7636d 100644 --- a/src/core/hle/D3D8/Direct3D9/VertexShader.h +++ b/src/core/hle/D3D8/Direct3D9/VertexShader.h @@ -4,6 +4,14 @@ #include "core\hle\D3D8\XbVertexShader.h" +enum class ShaderType { + Empty = 0, + Compilable, + Unsupported, +}; + +extern ShaderType EmuGetShaderInfo(IntermediateVertexShader* pIntermediateShader); + extern HRESULT EmuCompileShader ( IntermediateVertexShader* pIntermediateShader, diff --git a/src/core/hle/D3D8/Direct3D9/VertexShaderSource.cpp b/src/core/hle/D3D8/Direct3D9/VertexShaderSource.cpp new file mode 100644 index 000000000..c6aa69170 --- /dev/null +++ b/src/core/hle/D3D8/Direct3D9/VertexShaderSource.cpp @@ -0,0 +1,172 @@ +#define LOG_PREFIX CXBXR_MODULE::VSHCACHE + +#include "VertexShaderSource.h" + +#include "Logging.h" +#include "util/hasher.h" +#include "core/kernel/support/Emu.h" + +ID3DBlob* AsyncCreateVertexShader(IntermediateVertexShader intermediateShader, ShaderKey key) { + // HACK set thread affinity every call to reduce interference with Xbox main thread + // TODO use a thread pool library for better control over workers + SetThreadAffinityMask(GetCurrentThread(), g_CPUOthers); + + ID3DBlob* pCompiledShader; + + auto hRet = EmuCompileShader( + &intermediateShader, + &pCompiledShader + ); + + EmuLog(LOG_LEVEL::DEBUG, "Finished compiling shader %llx", key); + + return pCompiledShader; +} + +// Find a shader +// Return true if the shader was found + bool VertexShaderSource::_FindShader(ShaderKey key, LazyVertexShader** ppLazyShader) { + auto it = cache.find(key); + if (it == cache.end()) { + // We didn't find anything! Was CreateShader called? + EmuLog(LOG_LEVEL::WARNING, "No vertex shader found for key %llx", key); + return false; + } + + *ppLazyShader = &it->second; + return true; +} + + // Create a new shader + // If the shader was already created, just increase its reference count +ShaderKey VertexShaderSource::CreateShader(const DWORD* pXboxFunction, DWORD *pXboxFunctionSize) { + IntermediateVertexShader intermediateShader; + + // Parse into intermediate format + EmuParseVshFunction((DWORD*)pXboxFunction, + pXboxFunctionSize, + &intermediateShader); + + ShaderKey key = ComputeHash((void*)pXboxFunction, *pXboxFunctionSize); + + // Check if we need to create the shader + auto it = cache.find(key); + if (it != cache.end()) { + EmuLog(LOG_LEVEL::DEBUG, "Vertex shader %llx has been created already", key); + // Increment reference count + it->second.referenceCount++; + EmuLog(LOG_LEVEL::DEBUG, "Incremented ref count for shader %llx (%d)", key, it->second.referenceCount); + return key; + } + + // We're going to create a new shader + auto newShader = LazyVertexShader(); + newShader.referenceCount = 1; + + auto shaderType = EmuGetShaderInfo(&intermediateShader); + + if (shaderType == ShaderType::Compilable) + { + // Start compiling the shader in the background + // TODO proper threading / threadpool. + // We should have some control over the number and priority of threads + EmuLog(LOG_LEVEL::DEBUG, "Creating vertex shader %llx size %d", key, *pXboxFunctionSize); + newShader.compileResult = std::async(std::launch::async, AsyncCreateVertexShader, intermediateShader, key); + } + else { + // We can't do anything with this shader + newShader.isReady = true; + newShader.pHostVertexShader = nullptr; + } + + // Put the shader into the cache + cache[key] = std::move(newShader); + + return key; +} + +// Get a shader using the given key +IDirect3DVertexShader* VertexShaderSource::GetShader(ShaderKey key) +{ + LazyVertexShader* pLazyShader = nullptr; + + // Look for the shader in the cache + if (!_FindShader(key, &pLazyShader)) { + return nullptr; // we didn't find anything + } + + // If the shader is ready, return it + if (pLazyShader->isReady) { + return pLazyShader->pHostVertexShader; + } + + // If there's no D3DDevice set, return nullptr + if (pD3DDevice == nullptr) { + EmuLog(LOG_LEVEL::WARNING, "Can't create shader - no D3D device is set!"); + return nullptr; + } + + // We need to get the compiled HLSL and create a shader from it + ID3DBlob* pCompiledShader = nullptr; + try { + // TODO one day, check is_ready before logging this (non-standard..?) + EmuLog(LOG_LEVEL::DEBUG, "Waiting for shader %llx...", key); + pCompiledShader = pLazyShader->compileResult.get(); + + // Create the shader + auto hRet = pD3DDevice->CreateVertexShader + ( + (DWORD*)pCompiledShader->GetBufferPointer(), + &pLazyShader->pHostVertexShader + ); + + // TODO DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader"); + if (SUCCEEDED(hRet)) { + EmuLog(LOG_LEVEL::DEBUG, "Created new vertex shader instance for %llx", key); + } + else { + EmuLog(LOG_LEVEL::ERROR2, "Failed creating new vertex shader instance for %llx", key); + } + } + catch (const std::exception & e) { + EmuLog(LOG_LEVEL::ERROR2, "Failed compiling shader %llx: %s", e.what()); + } + + if (pCompiledShader) { + pCompiledShader->Release(); + + // TODO compile the shader at a higher optimization level in a background thread? + } + + // The shader is ready + pLazyShader->isReady = true; + + return pLazyShader->pHostVertexShader; +} + +// Release a shader. Doesn't actually release any resources for now +void VertexShaderSource::ReleaseShader(ShaderKey key) +{ + // For now, don't bother releasing any shaders + LazyVertexShader* pLazyShader; + if (_FindShader(key, &pLazyShader)) { + + if (pLazyShader->referenceCount > 0) { + pLazyShader->referenceCount--; + EmuLog(LOG_LEVEL::DEBUG, "Decremented ref count for shader %llx (%d)", key, pLazyShader->referenceCount); + } + else + { + EmuLog(LOG_LEVEL::DEBUG, "Release called on unreferenced shader %llx", key); + } + } + else { + EmuLog(LOG_LEVEL::WARNING, "Release called on non-existent shader!"); + } +} + +void VertexShaderSource::ResetD3DDevice(IDirect3DDevice* newDevice) +{ + EmuLog(LOG_LEVEL::DEBUG, "Resetting D3D device"); + this->pD3DDevice = newDevice; +} diff --git a/src/core/hle/D3D8/Direct3D9/VertexShaderSource.h b/src/core/hle/D3D8/Direct3D9/VertexShaderSource.h new file mode 100644 index 000000000..c8a7794a6 --- /dev/null +++ b/src/core/hle/D3D8/Direct3D9/VertexShaderSource.h @@ -0,0 +1,45 @@ + +#ifndef DIRECT3D9SHADERCACHE_H +#define DIRECT3D9SHADERCACHE_H + +#include "VertexShader.h" +#include + +typedef uint64_t ShaderKey; + +// Manages creation and caching of vertex shaders +class VertexShaderSource { + +public: + ShaderKey CreateShader(const DWORD* pXboxFunction, DWORD* pXboxFunctionSize); + IDirect3DVertexShader *GetShader(ShaderKey key); + void ReleaseShader(ShaderKey key); + + void ResetD3DDevice(IDirect3DDevice* pD3DDevice); + + // TODO + // WriteCacheToDisk + // LoadCacheFromDisk + +private: + struct LazyVertexShader { + bool isReady = false; + std::future compileResult; + IDirect3DVertexShader* pHostVertexShader = nullptr; + + // TODO when is it a good idea to releas eshaders? + int referenceCount = 0; + + // TODO persist shaders to disk + // ShaderVersion? + // OptimizationLevel? + }; + + IDirect3DDevice* pD3DDevice; + std::mutex cacheMutex; + std::map cache; + + bool VertexShaderSource::_FindShader(ShaderKey key, LazyVertexShader** ppLazyShader); +}; + +#endif diff --git a/src/core/hle/D3D8/XbVertexShader.cpp b/src/core/hle/D3D8/XbVertexShader.cpp index a48b4a3dd..f2fe929ec 100644 --- a/src/core/hle/D3D8/XbVertexShader.cpp +++ b/src/core/hle/D3D8/XbVertexShader.cpp @@ -1182,9 +1182,9 @@ public: // Free the preprocessed declaration copy free(pXboxVertexDeclarationCopy); + // Record which registers are in the vertex declaration for (size_t i = 0; i < RegVIsPresentInDeclaration.size(); i++) { pCxbxVertexShaderInfo->vRegisterInDeclaration[i] = RegVIsPresentInDeclaration[i]; - EmuLog(LOG_LEVEL::DEBUG, "Vertex regs used: v%d %d", i, pCxbxVertexShaderInfo->vRegisterInDeclaration[i]); } return Result; @@ -1316,7 +1316,7 @@ void CxbxImpl_SelectVertexShaderDirect } // parse xbox vertex shader function into an intermediate format -extern HRESULT EmuParseVshFunction +extern void EmuParseVshFunction ( DWORD* pXboxFunction, DWORD* pXboxFunctionSize, @@ -1325,13 +1325,6 @@ extern HRESULT EmuParseVshFunction { uint32_t* pToken; auto VshDecoder = XboxVertexShaderDecoder(); - ID3DBlob* pErrors = nullptr; - HRESULT hRet = 0; - - // TODO: support this situation.. - if (pXboxFunction == xbnullptr) { - return E_FAIL; - } *pXboxFunctionSize = 0; @@ -1347,7 +1340,4 @@ extern HRESULT EmuParseVshFunction // The size of the shader is pToken += X_VSH_INSTRUCTION_SIZE; // always at least one token *pXboxFunctionSize = (intptr_t)pToken - (intptr_t)pXboxFunction; - - - return hRet; } diff --git a/src/core/hle/D3D8/XbVertexShader.h b/src/core/hle/D3D8/XbVertexShader.h index eea6dbc7a..8e507c034 100644 --- a/src/core/hle/D3D8/XbVertexShader.h +++ b/src/core/hle/D3D8/XbVertexShader.h @@ -27,6 +27,7 @@ #include #include +#include #include "core\hle\D3D8\XbD3D8Types.h" // for X_VSH_MAX_ATTRIBUTES @@ -75,6 +76,7 @@ typedef struct _CxbxVertexShaderInfo } CxbxVertexShaderInfo; + typedef struct _CxbxVertexShader { // These are the parameters given by the XBE, @@ -89,7 +91,7 @@ typedef struct _CxbxVertexShader // The resulting host variables DWORD HostFVF; // Flexible Vertex Format (used when there's no host vertex shader) - IDirect3DVertexShader* pHostVertexShader; // if nullptr, use SetFVF(HostFVF); + uint64_t VertexShaderKey; // if nullptr, use SetFVF(HostFVF); IDirect3DVertexDeclaration* pHostVertexDeclaration; // Needed for dynamic stream patching @@ -216,7 +218,7 @@ typedef struct _IntermediateVertexShader { } IntermediateVertexShader; // parse xbox vertex shader function into an intermediate format -extern HRESULT EmuParseVshFunction +extern void EmuParseVshFunction ( DWORD* pXboxFunction, DWORD* pXboxFunctionSize, diff --git a/src/gui/DlgLoggingConfig.cpp b/src/gui/DlgLoggingConfig.cpp index c136c6433..679c31d54 100644 --- a/src/gui/DlgLoggingConfig.cpp +++ b/src/gui/DlgLoggingConfig.cpp @@ -57,6 +57,7 @@ static int g_DlgIndexes[] = { IDC_LOG_PSHB, IDC_LOG_PXSH, IDC_LOG_VTXSH, + IDC_LOG_VSHCACHE, IDC_LOG_VTXB, IDC_LOG_DINP, IDC_LOG_XINP, @@ -353,6 +354,7 @@ INT_PTR CALLBACK DlgLogConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM case IDC_LOG_PSHB: case IDC_LOG_PXSH: case IDC_LOG_VTXSH: + case IDC_LOG_VSHCACHE: case IDC_LOG_VTXB: case IDC_LOG_DINP: case IDC_LOG_XINP: diff --git a/src/gui/ResCxbx.h b/src/gui/ResCxbx.h index 916a3c96d..9ee9ebc0c 100644 --- a/src/gui/ResCxbx.h +++ b/src/gui/ResCxbx.h @@ -91,6 +91,7 @@ #define IDC_LOG_DSSTREAM 959 #define IDC_LOG_DS3DCALC 960 #define IDC_LOG_XMO 961 +#define IDC_LOG_VSHCACHE 962 #define IDC_SET_MOTOR 999 #define IDC_SET_X 1000 #define IDC_SET_Y 1001 @@ -368,7 +369,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 136 #define _APS_NEXT_COMMAND_VALUE 40113 -#define _APS_NEXT_CONTROL_VALUE 1277 +#define _APS_NEXT_CONTROL_VALUE 1278 #define _APS_NEXT_SYMED_VALUE 109 #endif #endif