mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 22:20:26 +00:00
wined3d: Shader cap fixes.
This commit is contained in:
parent
b550f34f2e
commit
194cdfa4b0
@ -517,7 +517,11 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
|
||||
gl_info->max_samplers = 1;
|
||||
gl_info->max_sampler_stages = 1;
|
||||
gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
|
||||
gl_info->ps_arb_max_temps = 0;
|
||||
gl_info->ps_arb_max_instructions = 0;
|
||||
gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
|
||||
gl_info->vs_arb_max_temps = 0;
|
||||
gl_info->vs_arb_max_instructions = 0;
|
||||
gl_info->vs_nv_version = VS_VERSION_NOT_SUPPORTED;
|
||||
gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
|
||||
gl_info->vs_glsl_constantsF = 0;
|
||||
@ -579,6 +583,12 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
|
||||
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
|
||||
TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - max float constants=%u\n", gl_max);
|
||||
gl_info->ps_arb_constantsF = gl_max;
|
||||
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max));
|
||||
TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - max temporaries=%u\n", gl_max);
|
||||
gl_info->ps_arb_max_temps = gl_max;
|
||||
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
|
||||
TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - max instructions=%u\n", gl_max);
|
||||
gl_info->ps_arb_max_instructions = gl_max;
|
||||
} else if (strcmp(ThisExtn, "GL_ARB_fragment_shader") == 0) {
|
||||
gl_info->supported[ARB_FRAGMENT_SHADER] = TRUE;
|
||||
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
|
||||
@ -636,6 +646,12 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
|
||||
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
|
||||
TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - max float constants=%u\n", gl_max);
|
||||
gl_info->vs_arb_constantsF = gl_max;
|
||||
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max));
|
||||
TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - max temporaries=%u\n", gl_max);
|
||||
gl_info->vs_arb_max_temps = gl_max;
|
||||
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
|
||||
TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - max instructions=%u\n", gl_max);
|
||||
gl_info->vs_arb_max_instructions = gl_max;
|
||||
} else if (strcmp(ThisExtn, "GL_ARB_vertex_shader") == 0) {
|
||||
gl_info->supported[ARB_VERTEX_SHADER] = TRUE;
|
||||
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
|
||||
@ -719,7 +735,7 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
|
||||
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Fog Distance support\n");
|
||||
gl_info->supported[NV_FOG_DISTANCE] = TRUE;
|
||||
} else if (strstr(ThisExtn, "GL_NV_fragment_program")) {
|
||||
gl_info->ps_nv_version = PS_VERSION_11;
|
||||
gl_info->ps_nv_version = (strcmp(ThisExtn, "GL_NV_fragment_program2") == 0) ? PS_VERSION_30 : PS_VERSION_20;
|
||||
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info->ps_nv_version);
|
||||
} else if (strcmp(ThisExtn, "GL_NV_register_combiners") == 0) {
|
||||
glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
|
||||
@ -748,8 +764,14 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
|
||||
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Occlusion Query (3) support\n");
|
||||
gl_info->supported[NV_OCCLUSION_QUERY] = TRUE;
|
||||
} else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
|
||||
gl_info->vs_nv_version = max(gl_info->vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program1_1")) ? VS_VERSION_11 : VS_VERSION_10);
|
||||
gl_info->vs_nv_version = max(gl_info->vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2")) ? VS_VERSION_20 : VS_VERSION_10);
|
||||
if(strcmp(ThisExtn, "GL_NV_vertex_program3") == 0)
|
||||
gl_info->vs_nv_version = VS_VERSION_30;
|
||||
else if(strcmp(ThisExtn, "GL_NV_vertex_program2") == 0)
|
||||
gl_info->vs_nv_version = VS_VERSION_20;
|
||||
else if(strcmp(ThisExtn, "GL_NV_vertex_program1_1") == 0)
|
||||
gl_info->vs_nv_version = VS_VERSION_11;
|
||||
else
|
||||
gl_info->vs_nv_version = VS_VERSION_10;
|
||||
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info->vs_nv_version);
|
||||
gl_info->supported[NV_VERTEX_PROGRAM] = TRUE;
|
||||
|
||||
@ -2018,6 +2040,13 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
|
||||
|
||||
/* FIXME: the shader mode should be per adapter */
|
||||
if (wined3d_settings.vs_selected_mode == SHADER_GLSL) {
|
||||
/* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
|
||||
models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
|
||||
vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for
|
||||
now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */
|
||||
if(This->gl_info.vs_nv_version == VS_VERSION_20)
|
||||
*pCaps->VertexShaderVersion = D3DVS_VERSION(2,0);
|
||||
else
|
||||
*pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
|
||||
TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
|
||||
} else if (wined3d_settings.vs_selected_mode == SHADER_ARB) {
|
||||
@ -2033,8 +2062,13 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
|
||||
|
||||
*pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
|
||||
|
||||
/* FIXME: the shader ode should be per adapter */
|
||||
/* FIXME: the shader mode should be per adapter */
|
||||
if (wined3d_settings.ps_selected_mode == SHADER_GLSL) {
|
||||
/* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program
|
||||
in case of GeforceFX cards. */
|
||||
if(This->gl_info.ps_nv_version == PS_VERSION_20)
|
||||
*pCaps->PixelShaderVersion = D3DPS_VERSION(2,0);
|
||||
else
|
||||
*pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
|
||||
/* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
|
||||
*pCaps->PixelShader1xMaxValue = 1.0;
|
||||
@ -2079,13 +2113,73 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
|
||||
#endif
|
||||
*pCaps->NumSimultaneousRTs = max_buffers;
|
||||
*pCaps->StretchRectFilterCaps = 0;
|
||||
*pCaps->VS20Caps.Caps = 0;
|
||||
*pCaps->PS20Caps.Caps = 0;
|
||||
*pCaps->VertexTextureFilterCaps = 0;
|
||||
*pCaps->MaxVShaderInstructionsExecuted = 0;
|
||||
*pCaps->MaxPShaderInstructionsExecuted = 0;
|
||||
|
||||
if(*pCaps->VertexShaderVersion == D3DVS_VERSION(3,0)) {
|
||||
/* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
|
||||
use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
|
||||
*pCaps->VS20Caps.Caps = D3DVS20CAPS_PREDICATION;
|
||||
*pCaps->VS20Caps.DynamicFlowControlDepth = D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
|
||||
*pCaps->VS20Caps.NumTemps = max(32, This->gl_info.vs_arb_max_temps);
|
||||
*pCaps->VS20Caps.StaticFlowControlDepth = D3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
|
||||
|
||||
*pCaps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs atleast 65535, some cards even use 2^32-1 */
|
||||
*pCaps->MaxVertexShader30InstructionSlots = max(512, This->gl_info.vs_arb_max_instructions);
|
||||
} else if(*pCaps->VertexShaderVersion == D3DVS_VERSION(2,0)) {
|
||||
*pCaps->VS20Caps.Caps = 0;
|
||||
*pCaps->VS20Caps.DynamicFlowControlDepth = D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
|
||||
*pCaps->VS20Caps.NumTemps = max(12, This->gl_info.vs_arb_max_temps);
|
||||
*pCaps->VS20Caps.StaticFlowControlDepth = 1;
|
||||
|
||||
*pCaps->MaxVShaderInstructionsExecuted = 65535;
|
||||
*pCaps->MaxVertexShader30InstructionSlots = 0;
|
||||
} else { /* VS 1.x */
|
||||
*pCaps->VS20Caps.Caps = 0;
|
||||
*pCaps->VS20Caps.DynamicFlowControlDepth = 0;
|
||||
*pCaps->VS20Caps.NumTemps = 0;
|
||||
*pCaps->VS20Caps.StaticFlowControlDepth = 0;
|
||||
|
||||
*pCaps->MaxVShaderInstructionsExecuted = 0;
|
||||
*pCaps->MaxVertexShader30InstructionSlots = 0;
|
||||
}
|
||||
|
||||
if(*pCaps->PixelShaderVersion == D3DPS_VERSION(3,0)) {
|
||||
/* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
|
||||
use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */
|
||||
|
||||
/* Caps is more or less undocumented on MSDN but it appears to be used for PS20Caps based on results from R9600/FX5900/Geforce6800 cards from Windows */
|
||||
*pCaps->PS20Caps.Caps = D3DPS20CAPS_ARBITRARYSWIZZLE |
|
||||
D3DPS20CAPS_GRADIENTINSTRUCTIONS |
|
||||
D3DPS20CAPS_PREDICATION |
|
||||
D3DPS20CAPS_NODEPENDENTREADLIMIT |
|
||||
D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
|
||||
*pCaps->PS20Caps.DynamicFlowControlDepth = D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
|
||||
*pCaps->PS20Caps.NumTemps = max(32, This->gl_info.ps_arb_max_temps);
|
||||
*pCaps->PS20Caps.StaticFlowControlDepth = D3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
|
||||
*pCaps->PS20Caps.NumInstructionSlots = D3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
|
||||
|
||||
*pCaps->MaxPShaderInstructionsExecuted = 65535;
|
||||
*pCaps->MaxPixelShader30InstructionSlots = max(D3DMIN30SHADERINSTRUCTIONS, This->gl_info.ps_arb_max_instructions);
|
||||
} else if(*pCaps->PixelShaderVersion == D3DPS_VERSION(2,0)) {
|
||||
/* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
|
||||
*pCaps->PS20Caps.Caps = 0;
|
||||
*pCaps->PS20Caps.DynamicFlowControlDepth = 0; /* D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
|
||||
*pCaps->PS20Caps.NumTemps = max(12, This->gl_info.ps_arb_max_temps);
|
||||
*pCaps->PS20Caps.StaticFlowControlDepth = D3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minumum: 1 */
|
||||
*pCaps->PS20Caps.NumInstructionSlots = D3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
|
||||
|
||||
*pCaps->MaxPShaderInstructionsExecuted = 512; /* Minimum value, a GeforceFX uses 1024 */
|
||||
*pCaps->MaxPixelShader30InstructionSlots = 0;
|
||||
} else { /* PS 1.x */
|
||||
*pCaps->PS20Caps.Caps = 0;
|
||||
*pCaps->PS20Caps.DynamicFlowControlDepth = 0;
|
||||
*pCaps->PS20Caps.NumTemps = 0;
|
||||
*pCaps->PS20Caps.StaticFlowControlDepth = 0;
|
||||
*pCaps->PS20Caps.NumInstructionSlots = 0;
|
||||
|
||||
*pCaps->MaxPShaderInstructionsExecuted = 0;
|
||||
*pCaps->MaxPixelShader30InstructionSlots = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
|
@ -1713,7 +1713,11 @@ typedef struct _WineD3D_GL_Info {
|
||||
unsigned max_pshader_constantsF;
|
||||
|
||||
unsigned vs_arb_constantsF;
|
||||
unsigned vs_arb_max_instructions;
|
||||
unsigned vs_arb_max_temps;
|
||||
unsigned ps_arb_constantsF;
|
||||
unsigned ps_arb_max_instructions;
|
||||
unsigned ps_arb_max_temps;
|
||||
unsigned vs_glsl_constantsF;
|
||||
unsigned ps_glsl_constantsF;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user