wined3d-SWVP-shaders, wined3d-Indexed_Vertex_Blending: Add new patch sets from Paul Gofman.

This commit is contained in:
Zebediah Figura
2019-02-27 20:23:10 -06:00
parent 7c1618b197
commit b02bd9c446
19 changed files with 2102 additions and 1504 deletions

View File

@@ -0,0 +1,303 @@
From 6b44ab2e3f778bf8b7837ea02dca26abdc1547a2 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Mon, 25 Feb 2019 13:17:01 +0300
Subject: [PATCH 1/5] wined3d: Use UBO for vertex shader float constants if
supported.
Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
dlls/wined3d/adapter_gl.c | 3 +
dlls/wined3d/glsl_shader.c | 113 +++++++++++++++++++++++++++++----
dlls/wined3d/shader.c | 2 +
dlls/wined3d/utils.c | 5 ++
dlls/wined3d/wined3d_private.h | 2 +
5 files changed, 114 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 48eca14fe2..493bca5d90 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -3081,6 +3081,9 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info, struct
gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX] = min(gl_max, WINED3D_MAX_CBS);
TRACE("Max vertex uniform blocks: %u (%d).\n",
gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX], gl_max);
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gl_max);
+ gl_info->limits.glsl_max_uniform_block_size = gl_max;
+ TRACE("Max uniform block size %u.\n", gl_max);
}
}
if (gl_info->supported[ARB_TESSELLATION_SHADER])
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 470cb0c3ba..625997470f 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -138,6 +138,10 @@ struct shader_glsl_priv
unsigned char *stack;
UINT next_constant_version;
+ BOOL consts_ubo;
+ GLuint ubo_vs_c;
+ struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F];
+
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
struct wine_rb_tree ffp_vertex_shaders;
@@ -189,6 +193,7 @@ struct glsl_vs_program
GLint pointsize_l_att_location;
GLint pointsize_q_att_location;
GLint clip_planes_location;
+ GLint vs_c_block_index;
};
struct glsl_hs_program
@@ -1145,12 +1150,48 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i
checkGLcall("walk_constant_heap_clamped()");
}
+static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv)
+{
+ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c));
+ checkGLcall("glBindBuffer");
+ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4),
+ NULL, GL_STREAM_DRAW));
+ checkGLcall("glBufferData");
+}
+
/* Context activation is done by the caller. */
static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap,
- unsigned char *stack, unsigned int version)
+ unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv)
{
const struct wined3d_shader_lconst *lconst;
+ BOOL is_vertex_shader = shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX;
+
+ if (is_vertex_shader && priv->consts_ubo)
+ {
+ const struct wined3d_vec4 *data;
+ unsigned max_const_used;
+
+ bind_and_orphan_consts_ubo(gl_info, priv);
+ max_const_used = shader->reg_maps.usesrelconstF
+ ? WINED3D_MAX_VS_CONSTS_F : shader->reg_maps.constant_float_count;
+ if (shader->load_local_constsF)
+ {
+ data = priv->vs_c_buffer;
+ memcpy(priv->vs_c_buffer, constants, max_const_used * sizeof(*constants));
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value;
+ }
+ }
+ else
+ {
+ data = constants;
+ }
+ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) * max_const_used, data));
+ checkGLcall("glBufferSubData");
+ return;
+ }
/* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
if (shader->reg_maps.shader_version.major == 1
@@ -1801,7 +1842,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
if (update_mask & WINED3D_SHADER_CONST_VS_F)
shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f,
- prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
+ prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version, priv);
if (update_mask & WINED3D_SHADER_CONST_VS_I)
shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i,
@@ -1954,7 +1995,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
if (update_mask & WINED3D_SHADER_CONST_PS_F)
shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f,
- prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
+ prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, priv);
if (update_mask & WINED3D_SHADER_CONST_PS_I)
shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i,
@@ -2093,6 +2134,9 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev
struct constant_heap *heap = &priv->vconst_heap;
UINT i;
+ if (priv->consts_ubo)
+ return;
+
for (i = start; i < count + start; ++i)
{
update_heap_entry(heap, i, priv->next_constant_version);
@@ -2408,6 +2452,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
const struct wined3d_shader_version *version = &reg_maps->shader_version;
const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args;
const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
+ struct shader_glsl_priv *priv = context->device->shader_priv;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_shader_indexable_temp *idx_temp_reg;
unsigned int uniform_block_base, uniform_block_count;
@@ -2425,7 +2470,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
/* Declare the constants (aka uniforms) */
- if (shader->limits->constant_float > 0)
+ if (shader->limits->constant_float > 0 && priv->consts_ubo
+ && version->type == WINED3D_SHADER_TYPE_VERTEX)
+ {
+ shader_addline(buffer,"layout(std140) uniform vs_c_ubo\n"
+ "{ \n"
+ " vec4 %s_c[%u];\n"
+ "};\n", prefix, min(shader->limits->constant_float, WINED3D_MAX_VS_CONSTS_F));
+ }
+ else if (shader->limits->constant_float > 0)
{
unsigned max_constantsF;
@@ -2490,11 +2543,12 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
else
{
- max_constantsF = gl_info->limits.glsl_vs_float_constants;
+ max_constantsF = reg_maps->constant_float_count;
}
}
max_constantsF = min(shader->limits->constant_float, max_constantsF);
- shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF);
+ if (max_constantsF)
+ shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF);
}
/* Always declare the full set of constants, the compiler can remove the
@@ -10101,17 +10155,44 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str
static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info,
- struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count)
+ struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs,
+ unsigned int vs_c_count)
{
unsigned int i;
struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers);
- for (i = 0; i < vs_c_count; ++i)
+ if (priv->consts_ubo && vs_c_count)
{
- string_buffer_sprintf(name, "vs_c[%u]", i);
- vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
+ unsigned int base, count;
+
+ vs->vs_c_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id, "vs_c_ubo"));
+ checkGLcall("glGetUniformBlockIndex");
+ if (vs->vs_c_block_index == -1)
+ ERR("Could not get ubo_vs_c block index.\n");
+
+ wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX,
+ &base, &count);
+ assert(count >= 1);
+ GL_EXTCALL(glUniformBlockBinding(program_id, vs->vs_c_block_index, base + count + 1));
+ checkGLcall("glUniformBlockBinding");
+ if (priv->ubo_vs_c == -1)
+ {
+ GL_EXTCALL(glGenBuffers(1, &priv->ubo_vs_c));
+ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c));
+ checkGLcall("glBindBuffer (UBO)");
+ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + count + 1, priv->ubo_vs_c));
+ checkGLcall("glBindBufferBase");
+ }
+ }
+ else if (!priv->consts_ubo)
+ {
+ for (i = 0; i < vs_c_count; ++i)
+ {
+ string_buffer_sprintf(name, "vs_c[%u]", i);
+ vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
+ }
+ memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint));
}
- memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint));
for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i)
{
@@ -11191,6 +11272,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
if (!(priv = heap_alloc_zero(sizeof(*priv))))
return E_OUTOFMEMORY;
+ priv->consts_ubo = gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT];
string_buffer_list_init(&priv->string_buffers);
if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
@@ -11245,6 +11327,8 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
device->fragment_priv = fragment_priv;
device->shader_priv = priv;
+ priv->ubo_vs_c = -1;
+
return WINED3D_OK;
fail:
@@ -11272,6 +11356,13 @@ static void shader_glsl_free(struct wined3d_device *device)
priv->fragment_pipe->free_private(device);
priv->vertex_pipe->vp_free(device);
+ if (priv->ubo_vs_c != -1)
+ {
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_vs_c));
+ checkGLcall("glDeleteBuffers");
+ priv->ubo_vs_c = -1;
+ }
heap_free(device->shader_priv);
device->shader_priv = NULL;
}
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 2db4a3cbc2..e34b6548cd 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -764,6 +764,8 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w
}
else
{
+ if (reg->idx[0].offset >= reg_maps->constant_float_count)
+ reg_maps->constant_float_count = reg->idx[0].offset + 1;
wined3d_insert_bits(reg_maps->constf, reg->idx[0].offset, 1, 0x1);
}
}
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index d77cb1ce11..104e276585 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6462,6 +6462,11 @@ void wined3d_gl_limits_get_uniform_block_range(const struct wined3d_gl_limits *g
if (i == shader_type)
return;
*base += *count;
+ if (i == WINED3D_SHADER_TYPE_VERTEX)
+ {
+ /* Reserve binding location for vs_c UBO. */
+ ++*base;
+ }
}
ERR("Unrecognized shader type %#x.\n", shader_type);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f23b84a6f4..b9ec04080d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1042,6 +1042,7 @@ struct wined3d_shader_reg_maps
struct wined3d_shader_tgsm *tgsm;
SIZE_T tgsm_capacity;
unsigned int tgsm_count;
+ UINT constant_float_count;
};
/* Keeps track of details for TEX_M#x# instructions which need to maintain
@@ -2580,6 +2581,7 @@ struct wined3d_gl_limits
UINT glsl_varyings;
UINT glsl_vs_float_constants;
UINT glsl_ps_float_constants;
+ UINT glsl_max_uniform_block_size;
UINT arb_vs_float_constants;
UINT arb_vs_native_constants;
--
2.20.1

View File

@@ -0,0 +1,145 @@
From b6f4150aa69d697f08abcf82ee59ffadb2fa6ad2 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Mon, 25 Feb 2019 14:24:50 +0300
Subject: [PATCH 2/5] d3d9: Support SWVP vertex shader float constants limits.
Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
dlls/d3d9/d3d9_private.h | 3 ++-
dlls/d3d9/device.c | 32 +++++++++++++++++++++++++-------
dlls/d3d9/directx.c | 2 +-
3 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 3fe0376e5c..300bee73c7 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -41,6 +41,7 @@
#include "wine/wined3d.h"
#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP 8192
#define D3D9_MAX_TEXTURE_UNITS 20
#define D3D9_MAX_STREAMS 16
@@ -57,7 +58,7 @@ enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_H
unsigned int wined3dmapflags_from_d3dmapflags(unsigned int flags, unsigned int usage) DECLSPEC_HIDDEN;
void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
const struct wined3d_swapchain_desc *swapchain_desc, DWORD presentation_interval) DECLSPEC_HIDDEN;
-void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps) DECLSPEC_HIDDEN;
+void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps, DWORD flags) DECLSPEC_HIDDEN;
struct d3d9
{
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 6cc3f180b0..03d2faf61a 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -362,7 +362,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
return TRUE;
}
-void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps)
+void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps, DWORD creation_flags)
{
static const DWORD ps_minor_version[] = {0, 4, 0, 0};
static const DWORD vs_minor_version[] = {0, 1, 0, 0};
@@ -500,7 +500,10 @@ void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const struct wined3d_caps *wined3d
D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP |
D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
- caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
+ if (creation_flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING)
+ caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP, caps->MaxVertexShaderConst);
+ else
+ caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
caps->NumSimultaneousRTs = min(D3D_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs);
if (caps->PixelShaderVersion > 3)
@@ -679,6 +682,7 @@ static HRESULT WINAPI d3d9_device_GetDirect3D(IDirect3DDevice9Ex *iface, IDirect
static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *caps)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_device_creation_parameters creation_parameters;
struct wined3d_caps wined3d_caps;
HRESULT hr;
@@ -687,13 +691,15 @@ static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCA
if (!caps)
return D3DERR_INVALIDCALL;
+ wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters);
+
memset(caps, 0, sizeof(*caps));
wined3d_mutex_lock();
hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps);
wined3d_mutex_unlock();
- d3dcaps_from_wined3dcaps(caps, &wined3d_caps);
+ d3dcaps_from_wined3dcaps(caps, &wined3d_caps, creation_parameters.flags);
return hr;
}
@@ -3418,14 +3424,20 @@ static HRESULT WINAPI d3d9_device_SetVertexShaderConstantF(IDirect3DDevice9Ex *i
UINT reg_idx, const float *data, UINT count)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_device_creation_parameters creation_parameters;
+ unsigned int max_constants;
HRESULT hr;
TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
- if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
+ wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters);
+ max_constants = creation_parameters.flags
+ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING)
+ ? D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP : D3D9_MAX_VERTEX_SHADER_CONSTANTF;
+ if (reg_idx + count > max_constants)
{
WARN("Trying to access %u constants, but d3d9 only supports %u\n",
- reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+ reg_idx + count, max_constants);
return D3DERR_INVALIDCALL;
}
@@ -3441,14 +3453,20 @@ static HRESULT WINAPI d3d9_device_GetVertexShaderConstantF(IDirect3DDevice9Ex *i
UINT reg_idx, float *data, UINT count)
{
struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_device_creation_parameters creation_parameters;
+ unsigned int max_constants;
HRESULT hr;
TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
- if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
+ wined3d_device_get_creation_parameters(device->wined3d_device, &creation_parameters);
+ max_constants = creation_parameters.flags
+ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING)
+ ? D3D9_MAX_VERTEX_SHADER_CONSTANTF_SWVP : D3D9_MAX_VERTEX_SHADER_CONSTANTF;
+ if (reg_idx + count > max_constants)
{
WARN("Trying to access %u constants, but d3d9 only supports %u\n",
- reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+ reg_idx + count, max_constants);
return D3DERR_INVALIDCALL;
}
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index eab114d19c..7c4defa169 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -371,7 +371,7 @@ static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DD
hr = wined3d_get_device_caps(d3d9->wined3d, adapter, device_type, &wined3d_caps);
wined3d_mutex_unlock();
- d3dcaps_from_wined3dcaps(caps, &wined3d_caps);
+ d3dcaps_from_wined3dcaps(caps, &wined3d_caps, 0);
return hr;
}
--
2.20.1

View File

@@ -0,0 +1,94 @@
From c028015c9ec3bcbeac6a57315f81e61f5b56a196 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Mon, 25 Feb 2019 14:47:28 +0300
Subject: [PATCH 3/5] wined3d: Report actual vertex shader float constants
limit for SWVP device.
Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
dlls/wined3d/adapter_gl.c | 3 ++-
dlls/wined3d/device.c | 13 ++++++++++++-
dlls/wined3d/glsl_shader.c | 5 ++++-
dlls/wined3d/wined3d_private.h | 2 ++
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 493bca5d90..1b386a7b8e 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -3731,7 +3731,8 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
d3d_info->limits.gs_version = shader_caps.gs_version;
d3d_info->limits.ps_version = shader_caps.ps_version;
d3d_info->limits.cs_version = shader_caps.cs_version;
- d3d_info->limits.vs_uniform_count = shader_caps.vs_uniform_count;
+ d3d_info->limits.vs_uniform_count_swvp = shader_caps.vs_uniform_count;
+ d3d_info->limits.vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, shader_caps.vs_uniform_count);
d3d_info->limits.ps_uniform_count = shader_caps.ps_uniform_count;
d3d_info->limits.varying_count = shader_caps.varying_count;
d3d_info->shader_double_precision = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index af73751dbf..0be43d4551 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3623,10 +3623,21 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d
HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps)
{
+ const struct wined3d_adapter *adapter = &device->wined3d->adapters[device->adapter->ordinal];
+ struct wined3d_vertex_caps vertex_caps;
+ HRESULT hr;
+
TRACE("device %p, caps %p.\n", device, caps);
- return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
+ hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
device->create_parms.device_type, caps);
+ if (FAILED(hr))
+ return hr;
+
+ adapter->vertex_pipe->vp_get_caps(&adapter->gl_info, &vertex_caps);
+ if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING)
+ caps->MaxVertexShaderConst = adapter->d3d_info.limits.vs_uniform_count_swvp;
+ return hr;
}
HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 625997470f..a1e75bf4d4 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -11438,7 +11438,10 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s
caps->vs_version = gl_info->supported[ARB_VERTEX_SHADER] ? caps->vs_version : 0;
caps->ps_version = gl_info->supported[ARB_FRAGMENT_SHADER] ? caps->ps_version : 0;
- caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants);
+ caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F_SWVP,
+ gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]
+ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4)
+ : gl_info->limits.glsl_vs_float_constants);
caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants);
caps->varying_count = gl_info->limits.glsl_varyings;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b9ec04080d..7100816279 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -163,6 +163,7 @@ struct wined3d_d3d_limits
{
unsigned int vs_version, hs_version, ds_version, gs_version, ps_version, cs_version;
DWORD vs_uniform_count;
+ DWORD vs_uniform_count_swvp;
DWORD ps_uniform_count;
unsigned int varying_count;
unsigned int ffp_textures;
@@ -672,6 +673,7 @@ enum wined3d_shader_conditional_op
#define WINED3D_MAX_CONSTS_B 16
#define WINED3D_MAX_CONSTS_I 16
#define WINED3D_MAX_VS_CONSTS_F 256
+#define WINED3D_MAX_VS_CONSTS_F_SWVP 8192
#define WINED3D_MAX_PS_CONSTS_F 224
/* FIXME: This needs to go up to 2048 for
--
2.20.1

View File

@@ -0,0 +1,191 @@
From 991225512f6251e7567d510028c69344811e7544 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Mon, 25 Feb 2019 15:05:12 +0300
Subject: [PATCH 4/5] wined3d: Support SWVP vertex shader constants limit in
state tracking.
Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
dlls/d3d9/tests/device.c | 5 -----
dlls/d3d9/tests/visual.c | 1 -
dlls/wined3d/device.c | 15 +++++++++++----
dlls/wined3d/glsl_shader.c | 2 +-
dlls/wined3d/stateblock.c | 6 +++---
dlls/wined3d/wined3d_private.h | 8 ++++----
6 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 030b34c4e4..5f7944b93a 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -6425,13 +6425,10 @@ static void test_vertex_shader_constant(void)
ok(consts_swvp == 8192, "Unexpected consts_swvp %u.\n", consts_swvp);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
@@ -6456,7 +6453,6 @@ static void test_vertex_shader_constant(void)
IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
@@ -6464,7 +6460,6 @@ static void test_vertex_shader_constant(void)
IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index e8279213d0..26085440fd 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -23948,7 +23948,6 @@ static void test_mvp_software_vertex_shaders(void)
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c_index, 1);
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShaderConstantF(device, (unsigned int)c_index[0], c_color, 1);
- todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_BeginScene(device);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 0be43d4551..ff0cb61f08 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2557,13 +2557,17 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device,
unsigned int start_idx, unsigned int count, const struct wined3d_vec4 *constants)
{
const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ unsigned int constants_count;
unsigned int i;
TRACE("device %p, start_idx %u, count %u, constants %p.\n",
device, start_idx, count, constants);
- if (!constants || start_idx >= d3d_info->limits.vs_uniform_count
- || count > d3d_info->limits.vs_uniform_count - start_idx)
+ constants_count = device->create_parms.flags
+ & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING)
+ ? d3d_info->limits.vs_uniform_count_swvp : d3d_info->limits.vs_uniform_count;
+ if (!constants || start_idx >= constants_count
+ || count > constants_count - start_idx)
return WINED3DERR_INVALIDCALL;
memcpy(&device->update_stateblock_state->vs_consts_f[start_idx], constants, count * sizeof(*constants));
@@ -2590,12 +2594,15 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device
unsigned int start_idx, unsigned int count, struct wined3d_vec4 *constants)
{
const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ unsigned int constants_count;
TRACE("device %p, start_idx %u, count %u, constants %p.\n",
device, start_idx, count, constants);
- if (!constants || start_idx >= d3d_info->limits.vs_uniform_count
- || count > d3d_info->limits.vs_uniform_count - start_idx)
+ constants_count = device->create_parms.flags & WINED3DCREATE_HARDWARE_VERTEXPROCESSING
+ ? d3d_info->limits.vs_uniform_count : d3d_info->limits.vs_uniform_count_swvp;
+ if (!constants || start_idx >= constants_count
+ || count > constants_count - start_idx)
return WINED3DERR_INVALIDCALL;
memcpy(constants, &device->state.vs_consts_f[start_idx], count * sizeof(*constants));
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index a1e75bf4d4..8fdab07ab0 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2137,7 +2137,7 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev
if (priv->consts_ubo)
return;
- for (i = start; i < count + start; ++i)
+ for (i = start; i < min(WINED3D_MAX_VS_CONSTS_F, count + start); ++i)
{
update_heap_entry(heap, i, priv->next_constant_version);
}
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 820089d0b8..cd5c8bd5dc 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -316,7 +316,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
}
}
- for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i)
+ for (i = 0; i < d3d_info->limits.vs_uniform_count_swvp; ++i)
{
if (stateblock->changed.vs_consts_f[i])
{
@@ -1572,7 +1572,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
stateblock_init_lights(stateblock->stateblock_state.light_state.light_map,
device->stateblock_state.light_state.light_map);
stateblock_savedstates_set_all(&stateblock->changed,
- d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count);
+ d3d_info->limits.vs_uniform_count_swvp, d3d_info->limits.ps_uniform_count);
break;
case WINED3D_SBT_PIXEL_STATE:
@@ -1584,7 +1584,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
stateblock_init_lights(stateblock->stateblock_state.light_state.light_map,
device->stateblock_state.light_state.light_map);
stateblock_savedstates_set_vertex(&stateblock->changed,
- d3d_info->limits.vs_uniform_count);
+ d3d_info->limits.vs_uniform_count_swvp);
break;
default:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7100816279..51214d89dc 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2937,7 +2937,7 @@ struct wined3d_state
BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
- struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+ struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I];
@@ -3009,7 +3009,7 @@ struct wined3d_stateblock_state
int base_vertex_index;
struct wined3d_shader *vs;
- struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+ struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
@@ -3604,7 +3604,7 @@ struct wined3d_saved_states
BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
WORD vertexShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */
WORD vertexShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */
- BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+ BOOL vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
DWORD textures : 20; /* WINED3D_MAX_COMBINED_SAMPLERS, 20 */
DWORD indices : 1;
DWORD material : 1;
@@ -3640,7 +3640,7 @@ struct wined3d_stateblock
unsigned int num_contained_vs_consts_i;
DWORD contained_vs_consts_b[WINED3D_MAX_CONSTS_B];
unsigned int num_contained_vs_consts_b;
- DWORD contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+ DWORD contained_vs_consts_f[WINED3D_MAX_VS_CONSTS_F_SWVP];
unsigned int num_contained_vs_consts_f;
DWORD contained_ps_consts_i[WINED3D_MAX_CONSTS_I];
unsigned int num_contained_ps_consts_i;
--
2.20.1

View File

@@ -0,0 +1,492 @@
From dd16fac7bbbc3a9197d1866e59d945a1552cc654 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Mon, 25 Feb 2019 15:23:33 +0300
Subject: [PATCH 5/5] wined3d: Support SWVP mode vertex shaders.
Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
dlls/d3d9/tests/device.c | 16 ++------
dlls/d3d9/tests/visual.c | 5 +--
dlls/wined3d/device.c | 8 ++++
dlls/wined3d/glsl_shader.c | 69 +++++++++++++++++++++++++---------
dlls/wined3d/shader.c | 44 +++++++++++++++-------
dlls/wined3d/shader_sm1.c | 2 +-
dlls/wined3d/wined3d_private.h | 7 ++++
7 files changed, 103 insertions(+), 48 deletions(-)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 5f7944b93a..cef0759610 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -6913,15 +6913,11 @@ float4 main(const float4 color : COLOR) : SV_TARGET
vs = NULL;
hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- if (vs)
- IDirect3DVertexShader9_Release(vs);
+ IDirect3DVertexShader9_Release(vs);
hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- if (vs)
- IDirect3DVertexShader9_Release(vs);
+ IDirect3DVertexShader9_Release(vs);
refcount = IDirect3DDevice9_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
@@ -6938,20 +6934,16 @@ float4 main(const float4 color : COLOR) : SV_TARGET
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShader(device, vs);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- if (vs)
- IDirect3DVertexShader9_Release(vs);
+ IDirect3DVertexShader9_Release(vs);
hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
- todo_wine
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_SetVertexShader(device, vs);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- if (vs)
- IDirect3DVertexShader9_Release(vs);
+ IDirect3DVertexShader9_Release(vs);
cleanup:
refcount = IDirect3DDevice9_Release(device);
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 26085440fd..67e1133c51 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -23874,7 +23874,6 @@ static void test_mvp_software_vertex_shaders(void)
hr = IDirect3DDevice9_CreateVertexShader(device, reladdr_shader_code, &reladdr_shader);
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_CreateVertexShader(device, pure_sw_shader_code, &pure_sw_shader);
- todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
@@ -23912,7 +23911,7 @@ static void test_mvp_software_vertex_shaders(void)
expected_color = 0x00ff0000; /* Color from vertex data and not from the shader. */
color = getPixelColor(device, 5, 5);
- ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode, second attempt).\n",
+ todo_wine ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode, second attempt).\n",
expected_color, color);
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
@@ -23931,7 +23930,6 @@ static void test_mvp_software_vertex_shaders(void)
expected_color = 0x00ffffff;
color = getPixelColor(device, 5, 5);
- todo_wine
ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in sw mode).\n",
expected_color, color);
@@ -23981,7 +23979,6 @@ static void test_mvp_software_vertex_shaders(void)
expected_color = 0x0000ffff; /* c[256] is c_color for SW shader. */
color = getPixelColor(device, 5, 5);
- todo_wine
ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in sw mode).\n",
expected_color, color);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index ff0cb61f08..307993286c 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4079,6 +4079,14 @@ void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *
warned = TRUE;
}
+ wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
+ if (!device->softwareVertexProcessing != !software)
+ {
+ unsigned int i;
+
+ for (i = 0; i < device->context_count; ++i)
+ device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
+ }
device->softwareVertexProcessing = software;
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 8fdab07ab0..b7ccfc633e 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -140,7 +140,9 @@ struct shader_glsl_priv
BOOL consts_ubo;
GLuint ubo_vs_c;
- struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F];
+ BOOL prev_device_swvp;
+ struct wined3d_vec4 vs_c_buffer[WINED3D_MAX_VS_CONSTS_F_SWVP];
+ unsigned int max_vs_consts_f;
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
@@ -155,7 +157,7 @@ struct glsl_vs_program
struct list shader_entry;
GLuint id;
GLenum vertex_color_clamp;
- GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F];
+ GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F_SWVP];
GLint uniform_i_locations[WINED3D_MAX_CONSTS_I];
GLint uniform_b_locations[WINED3D_MAX_CONSTS_B];
GLint pos_fixup_location;
@@ -1154,7 +1156,7 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st
{
GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_vs_c));
checkGLcall("glBindBuffer");
- GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, WINED3D_MAX_VS_CONSTS_F * sizeof(struct wined3d_vec4),
+ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER, priv->max_vs_consts_f * sizeof(struct wined3d_vec4),
NULL, GL_STREAM_DRAW));
checkGLcall("glBufferData");
}
@@ -1162,33 +1164,45 @@ static void bind_and_orphan_consts_ubo(const struct wined3d_gl_info *gl_info, st
/* Context activation is done by the caller. */
static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap,
- unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv)
+ unsigned char *stack, unsigned int version, struct shader_glsl_priv *priv, BOOL device_swvp)
{
const struct wined3d_shader_lconst *lconst;
BOOL is_vertex_shader = shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX;
if (is_vertex_shader && priv->consts_ubo)
{
+ BOOL zero_sw_constants = !device_swvp && priv->prev_device_swvp;
const struct wined3d_vec4 *data;
+ unsigned int const_count;
unsigned max_const_used;
bind_and_orphan_consts_ubo(gl_info, priv);
- max_const_used = shader->reg_maps.usesrelconstF
- ? WINED3D_MAX_VS_CONSTS_F : shader->reg_maps.constant_float_count;
- if (shader->load_local_constsF)
+ const_count = device_swvp ? priv->max_vs_consts_f : WINED3D_MAX_VS_CONSTS_F;
+ max_const_used = shader->reg_maps.usesrelconstF ? const_count : shader->reg_maps.constant_float_count;
+ if (shader->load_local_constsF || (zero_sw_constants && shader->reg_maps.usesrelconstF))
{
data = priv->vs_c_buffer;
memcpy(priv->vs_c_buffer, constants, max_const_used * sizeof(*constants));
- LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ if (zero_sw_constants)
{
- priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value;
+ memset(&priv->vs_c_buffer[const_count], 0, (priv->max_vs_consts_f - WINED3D_MAX_VS_CONSTS_F)
+ * sizeof(*constants));
+ priv->prev_device_swvp = FALSE;
+ }
+ if (shader->load_local_constsF)
+ {
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ priv->vs_c_buffer[lconst->idx] = *(const struct wined3d_vec4 *)lconst->value;
+ }
}
}
else
{
data = constants;
}
- GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants) * max_const_used, data));
+ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*constants)
+ * (zero_sw_constants ? priv->max_vs_consts_f : max_const_used), data));
checkGLcall("glBufferSubData");
return;
}
@@ -1842,7 +1856,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
if (update_mask & WINED3D_SHADER_CONST_VS_F)
shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f,
- prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version, priv);
+ prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack,
+ constant_version, priv, device_is_swvp(context->device));
if (update_mask & WINED3D_SHADER_CONST_VS_I)
shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i,
@@ -1995,7 +2010,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
if (update_mask & WINED3D_SHADER_CONST_PS_F)
shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f,
- prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version, priv);
+ prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version,
+ priv, FALSE);
if (update_mask & WINED3D_SHADER_CONST_PS_I)
shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i,
@@ -2137,7 +2153,7 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev
if (priv->consts_ubo)
return;
- for (i = start; i < min(WINED3D_MAX_VS_CONSTS_F, count + start); ++i)
+ for (i = start; i < count + start; ++i)
{
update_heap_entry(heap, i, priv->next_constant_version);
}
@@ -2476,7 +2492,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
shader_addline(buffer,"layout(std140) uniform vs_c_ubo\n"
"{ \n"
" vec4 %s_c[%u];\n"
- "};\n", prefix, min(shader->limits->constant_float, WINED3D_MAX_VS_CONSTS_F));
+ "};\n", prefix, min(shader->limits->constant_float, priv->max_vs_consts_f));
}
else if (shader->limits->constant_float > 0)
{
@@ -10186,12 +10202,13 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *
}
else if (!priv->consts_ubo)
{
- for (i = 0; i < vs_c_count; ++i)
+ for (i = 0; i < min(vs_c_count, priv->max_vs_consts_f); ++i)
{
string_buffer_sprintf(name, "vs_c[%u]", i);
vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
}
- memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint));
+ if (vs_c_count < priv->max_vs_consts_f)
+ memset(&vs->uniform_f_locations[vs_c_count], 0xff, (priv->max_vs_consts_f - vs_c_count) * sizeof(GLuint));
}
for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i)
@@ -10510,6 +10527,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
vs_list = &ffp_shader->linked_programs;
}
+ if (vshader && vshader->reg_maps.constant_float_count > WINED3D_MAX_VS_CONSTS_F
+ && !device_is_swvp(context->device))
+ FIXME("Applying context with SW shader in HW mode.\n");
+
hshader = state->shader[WINED3D_SHADER_TYPE_HULL];
if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program)
hs_id = ctx_data->glsl_program->hs.id;
@@ -11263,7 +11284,7 @@ static void constant_heap_free(struct constant_heap *heap)
static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
const struct fragment_pipeline *fragment_pipe)
{
- SIZE_T stack_size = wined3d_log2i(max(WINED3D_MAX_VS_CONSTS_F, WINED3D_MAX_PS_CONSTS_F)) + 1;
+ SIZE_T stack_size;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct fragment_caps fragment_caps;
void *vertex_priv, *fragment_priv;
@@ -11273,6 +11294,18 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
return E_OUTOFMEMORY;
priv->consts_ubo = gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT];
+ priv->max_vs_consts_f = priv->consts_ubo
+ ? gl_info->limits.glsl_max_uniform_block_size / sizeof(struct wined3d_vec4)
+ : gl_info->limits.glsl_vs_float_constants;
+
+ if (!(device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING | WINED3DCREATE_MIXED_VERTEXPROCESSING)))
+ priv->max_vs_consts_f = min(priv->max_vs_consts_f, WINED3D_MAX_VS_CONSTS_F);
+
+ stack_size = priv->consts_ubo
+ ? wined3d_log2i(WINED3D_MAX_PS_CONSTS_F) + 1
+ : wined3d_log2i(max(priv->max_vs_consts_f, WINED3D_MAX_PS_CONSTS_F)) + 1;
+ TRACE("consts_ubo %#x, max_vs_consts_f %u.\n", priv->consts_ubo, priv->max_vs_consts_f);
+
string_buffer_list_init(&priv->string_buffers);
if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
@@ -11302,7 +11335,7 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
goto fail;
}
- if (!constant_heap_init(&priv->vconst_heap, WINED3D_MAX_VS_CONSTS_F))
+ if (!priv->consts_ubo && !constant_heap_init(&priv->vconst_heap, priv->max_vs_consts_f))
{
ERR("Failed to initialize vertex shader constant heap\n");
goto fail;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index e34b6548cd..965471e0e5 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -589,7 +589,7 @@ static void shader_delete_constant_list(struct list *clist)
list_init(clist);
}
-static void shader_set_limits(struct wined3d_shader *shader)
+static void shader_set_limits(struct wined3d_shader *shader, BOOL swvp)
{
static const struct limits_entry
{
@@ -612,6 +612,19 @@ static void shader_set_limits(struct wined3d_shader *shader)
{WINED3D_SHADER_VERSION(4, 1), WINED3D_SHADER_VERSION(5, 0), {16, 0, 0, 0, 32, 0}},
{0}
},
+ vs_limits_swvp[] =
+ {
+ /* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packed_input */
+ {WINED3D_SHADER_VERSION(1, 0), WINED3D_SHADER_VERSION(1, 1), { 0, 0, 8192, 0, 12, 0}},
+ {WINED3D_SHADER_VERSION(2, 0), WINED3D_SHADER_VERSION(2, 255), { 0, 16, 8192, 16, 12, 0}},
+ /* DX10 cards on Windows advertise a D3D9 constant limit of 256
+ * even though they are capable of supporting much more (GL
+ * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
+ * wined3d-advertised maximum. Clamp the constant limit for <= 3.0
+ * shaders to 256. */
+ {WINED3D_SHADER_VERSION(3, 0), WINED3D_SHADER_VERSION(3, 255), { 4, 16, 8192, 16, 12, 0}},
+ {0}
+ },
hs_limits[] =
{
/* min_version, max_version, sampler, constant_int, constant_float, constant_bool, packed_output, packet_input */
@@ -656,7 +669,7 @@ static void shader_set_limits(struct wined3d_shader *shader)
FIXME("Unexpected shader type %u found.\n", shader->reg_maps.shader_version.type);
/* Fall-through. */
case WINED3D_SHADER_TYPE_VERTEX:
- limits_array = vs_limits;
+ limits_array = swvp ? vs_limits_swvp : vs_limits;
break;
case WINED3D_SHADER_TYPE_HULL:
limits_array = hs_limits;
@@ -1024,7 +1037,7 @@ static HRESULT shader_scan_output_signature(struct wined3d_shader *shader)
}
/* Note that this does not count the loop register as an address register. */
-static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size)
+static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size, BOOL swvp)
{
struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT];
@@ -1050,7 +1063,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
prev_ins = current_ins = ptr;
reg_maps->shader_version = shader_version;
- shader_set_limits(shader);
+ shader_set_limits(shader, swvp);
if (!(reg_maps->constf = heap_calloc(((min(shader->limits->constant_float, constf_size) + 31) / 32),
sizeof(*reg_maps->constf))))
@@ -3334,7 +3347,7 @@ static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_l
}
static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d_device *device,
- enum wined3d_shader_type type, unsigned int float_const_count)
+ enum wined3d_shader_type type, unsigned int float_const_count, BOOL swvp)
{
const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
@@ -3359,7 +3372,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, struct wined3d
shader_trace_init(fe, shader->frontend_data);
/* Second pass: figure out which registers are used, what the semantics are, etc. */
- if (FAILED(hr = shader_get_registers_used(shader, float_const_count)))
+ if (FAILED(hr = shader_get_registers_used(shader, float_const_count, swvp)))
return hr;
if (version->type != type)
@@ -3699,14 +3712,19 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_
const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
{
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ unsigned int vs_uniform_count;
unsigned int i;
HRESULT hr;
+ BOOL swvp = device->create_parms.flags & (WINED3DCREATE_SOFTWARE_VERTEXPROCESSING
+ | WINED3DCREATE_MIXED_VERTEXPROCESSING);
if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops)))
return hr;
+ vs_uniform_count = swvp ? device->adapter->d3d_info.limits.vs_uniform_count_swvp
+ : device->adapter->d3d_info.limits.vs_uniform_count;
if (FAILED(hr = shader_set_function(shader, device,
- WINED3D_SHADER_TYPE_VERTEX, device->adapter->d3d_info.limits.vs_uniform_count)))
+ WINED3D_SHADER_TYPE_VERTEX, vs_uniform_count, swvp)))
{
shader_cleanup(shader);
return hr;
@@ -3810,7 +3828,7 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
{
shader->reg_maps.shader_version = shader_version;
shader->reg_maps.shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
- shader_set_limits(shader);
+ shader_set_limits(shader, 0);
if (FAILED(hr = shader_scan_output_signature(shader)))
return hr;
}
@@ -3863,7 +3881,7 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3
goto fail;
if (shader->function
- && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0)))
+ && FAILED(hr = shader_set_function(shader, device, WINED3D_SHADER_TYPE_GEOMETRY, 0, 0)))
goto fail;
return WINED3D_OK;
@@ -4164,7 +4182,7 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d
return hr;
if (FAILED(hr = shader_set_function(shader, device,
- WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count)))
+ WINED3D_SHADER_TYPE_PIXEL, device->adapter->d3d_info.limits.ps_uniform_count, 0)))
{
shader_cleanup(shader);
return hr;
@@ -4264,7 +4282,7 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru
return hr;
}
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0)))
+ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_COMPUTE, 0, 0)))
{
shader_cleanup(object);
heap_free(object);
@@ -4298,7 +4316,7 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru
return hr;
}
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0)))
+ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_DOMAIN, 0, 0)))
{
shader_cleanup(object);
heap_free(object);
@@ -4360,7 +4378,7 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru
return hr;
}
- if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0)))
+ if (FAILED(hr = shader_set_function(object, device, WINED3D_SHADER_TYPE_HULL, 0, 0)))
{
shader_cleanup(object);
heap_free(object);
diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c
index 0c6bb93317..1051307e88 100644
--- a/dlls/wined3d/shader_sm1.c
+++ b/dlls/wined3d/shader_sm1.c
@@ -543,7 +543,7 @@ static void *shader_sm1_init(const DWORD *byte_code, size_t byte_code_size,
major = WINED3D_SM1_VERSION_MAJOR(*byte_code);
minor = WINED3D_SM1_VERSION_MINOR(*byte_code);
- if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0))
+ if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 255))
{
WARN("Invalid shader version %u.%u (%#x).\n", major, minor, *byte_code);
return NULL;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 51214d89dc..7014e6760d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4415,6 +4415,13 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader,
return FALSE;
}
+static inline BOOL device_is_swvp(const struct wined3d_device *device)
+{
+ return (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING)
+ || ((device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING)
+ && device->softwareVertexProcessing);
+}
+
void get_identity_matrix(struct wined3d_matrix *mat) DECLSPEC_HIDDEN;
void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state,
unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN;
--
2.20.1

View File

@@ -0,0 +1,2 @@
Fixes: [8051] Sims 2 demo exits prematurely
Depends: wined3d-WINED3D_RS_COLORWRITEENABLE