diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 6efa7fc2742..db04c6a166d 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -997,7 +997,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont if (!pshader) { shader_addline(buffer, "uniform vec4 posFixup;\n"); - shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT); + shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits.packed_output); } else { @@ -3997,7 +3997,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer if (ps_major < 3) { - shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", MAX_REG_OUTPUT); + shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output); for (i = 0; map; map >>= 1, ++i) { @@ -4053,7 +4053,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits.packed_input); /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */ shader_addline(buffer, "varying vec4 ps_in[%u];\n", in_count); - shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", MAX_REG_OUTPUT); + shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output); /* First, sort out position and point size. Those are not passed to the pixel shader */ for (i = 0; map; map >>= 1, ++i) diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index bcff6b15e1d..72f2fa6fd35 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -1779,10 +1779,6 @@ static void vertexshader_set_limits(struct wined3d_shader *shader) shader->limits.constant_float = min(256, device->d3d_vshader_constantF); break; - case WINED3D_SHADER_VERSION(4, 0): - FIXME("Using 3.0 limits for 4.0 shader.\n"); - /* Fall through. */ - case WINED3D_SHADER_VERSION(3, 0): shader->limits.temporary = 32; shader->limits.constant_bool = 32; @@ -1799,6 +1795,19 @@ static void vertexshader_set_limits(struct wined3d_shader *shader) shader->limits.constant_float = min(256, device->d3d_vshader_constantF); break; + case WINED3D_SHADER_VERSION(4, 0): + shader->limits.temporary = 32; /* FIXME: 4096 */ + shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */ + shader->limits.constant_int = 0; + shader->limits.constant_float = 0; + shader->limits.constant_bool = 0; + shader->limits.address = 1; + shader->limits.packed_output = 16; + shader->limits.packed_input = 0; + shader->limits.attributes = 16; + shader->limits.label = 16; + break; + default: shader->limits.temporary = 12; shader->limits.constant_bool = 16; @@ -1864,6 +1873,35 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d return WINED3D_OK; } +static void geometryshader_set_limits(struct wined3d_shader *shader) +{ + DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major, + shader->reg_maps.shader_version.minor); + + switch (shader_version) + { + case WINED3D_SHADER_VERSION(4, 0): + shader->limits.temporary = 32; /* FIXME: 4096 */ + shader->limits.texcoord = 0; + shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */ + shader->limits.constant_int = 0; + shader->limits.constant_float = 0; + shader->limits.constant_bool = 0; + shader->limits.address = 1; + shader->limits.packed_output = 32; + shader->limits.packed_input = 16; + shader->limits.attributes = 0; + shader->limits.label = 16; + break; + + default: + memset(&shader->limits, 0, sizeof(shader->limits)); + FIXME("Unhandled geometry shader version \"%u.%u\".\n", + shader->reg_maps.shader_version.major, + shader->reg_maps.shader_version.minor); + } +} + static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d_device *device, const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version) @@ -1880,6 +1918,8 @@ static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d return hr; } + geometryshader_set_limits(shader); + shader->load_local_constsF = FALSE; return WINED3D_OK; @@ -2092,10 +2132,6 @@ static void pixelshader_set_limits(struct wined3d_shader *shader) shader->limits.label = 16; break; - case WINED3D_SHADER_VERSION(4, 0): - FIXME("Using 3.0 limits for 4.0 shader.\n"); - /* Fall through. */ - case WINED3D_SHADER_VERSION(3, 0): shader->limits.temporary = 32; shader->limits.constant_float = 224; @@ -2107,6 +2143,18 @@ static void pixelshader_set_limits(struct wined3d_shader *shader) shader->limits.label = 16; /* FIXME: 2048 */ break; + case WINED3D_SHADER_VERSION(4, 0): + shader->limits.temporary = 32; /* FIXME: 4096 */ + shader->limits.texcoord = 0; + shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */ + shader->limits.constant_int = 0; + shader->limits.constant_float = 0; + shader->limits.constant_bool = 0; + shader->limits.address = 1; + shader->limits.packed_input = 32; + shader->limits.label = 16; + break; + default: shader->limits.temporary = 32; shader->limits.constant_float = 32; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 258ac2d2238..b5fd4f07849 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -404,8 +404,8 @@ enum wined3d_shader_rel_op #define MAX_REG_ADDR 1 #define MAX_REG_TEMP 32 #define MAX_REG_TEXCRD 8 -#define MAX_REG_INPUT 12 -#define MAX_REG_OUTPUT 12 +#define MAX_REG_INPUT 32 +#define MAX_REG_OUTPUT 32 #define MAX_CONST_I 16 #define MAX_CONST_B 16 @@ -563,8 +563,8 @@ struct wined3d_shader_reg_maps DWORD temporary; /* MAX_REG_TEMP, 32 */ DWORD *constf; /* pixel, vertex */ DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */ - WORD input_registers; /* max(MAX_REG_INPUT, MAX_ATTRIBS), 16 */ - WORD output_registers; /* MAX_REG_OUTPUT, 12 */ + DWORD input_registers; /* max(MAX_REG_INPUT, MAX_ATTRIBS), 32 */ + DWORD output_registers; /* MAX_REG_OUTPUT, 32 */ WORD integer_constants; /* MAX_CONST_I, 16 */ WORD boolean_constants; /* MAX_CONST_B, 16 */ WORD local_int_consts; /* MAX_CONST_I, 16 */