Merge pull request #1828 from NZJenkins/vertex_shader_source

Vertex shader runtime cache
This commit is contained in:
Luke Usher 2020-02-08 09:24:10 +00:00 committed by GitHub
commit 51d5759a1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 444 additions and 273 deletions

View File

@ -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"

View File

@ -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
/////////////////////////////////////////////////////////////////////////////

View File

@ -58,6 +58,7 @@ const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)] = {
"PSHB ",
"PXSH ",
"VTXSH ",
"VSHCACHE",
"VTXB ",
"DINP ",
"XINP ",

View File

@ -66,6 +66,7 @@ typedef enum class _CXBXR_MODULE: unsigned int {
PSHB,
PXSH,
VTXSH,
VSHCACHE,
VTXB,
DINP,
XINP,

View File

@ -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 <assert.h>
#include <process.h>
@ -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_key_t, resource_info_t, resource_key_hash> 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)
{

View File

@ -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"

View File

@ -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,

View File

@ -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;
}

View File

@ -0,0 +1,45 @@
#ifndef DIRECT3D9SHADERCACHE_H
#define DIRECT3D9SHADERCACHE_H
#include "VertexShader.h"
#include <map>
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<ID3DBlob*> 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<ShaderKey, LazyVertexShader> cache;
bool VertexShaderSource::_FindShader(ShaderKey key, LazyVertexShader** ppLazyShader);
};
#endif

View File

@ -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;
}

View File

@ -27,6 +27,7 @@
#include <d3dcompiler.h>
#include <vector>
#include <future>
#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,

View File

@ -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:

View File

@ -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