Commit c065b4fe authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

wined3d: Store push constants in wined3d_buffers in struct wined3d_state.

We will need them in buffers for Vulkan, as well as for software vertex shaders. Currently we simply store them in sysmem buffers and read directly back out of them to load GL uniforms. This does decrease memory usage a bit for d3d10+.
parent 5323042f
......@@ -520,11 +520,15 @@ static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info
/* Context activation is done by the caller. */
static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *gl_shader,
const struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int rt_height)
struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int rt_height)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_device *device = context_gl->c.device;
const struct wined3d_ivec4 *int_consts;
unsigned char i;
int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], &context_gl->c);
for(i = 0; i < gl_shader->numbumpenvmatconsts; i++)
{
int texunit = gl_shader->bumpenvmatconst[i].texunit;
......@@ -571,9 +575,9 @@ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *g
if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED)
{
float val[4];
val[0] = (float)state->ps_consts_i[i].x;
val[1] = (float)state->ps_consts_i[i].y;
val[2] = (float)state->ps_consts_i[i].z;
val[0] = (float)int_consts[i].x;
val[1] = (float)int_consts[i].y;
val[2] = (float)int_consts[i].z;
val[3] = -1.0f;
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->int_consts[i], val));
......@@ -584,9 +588,11 @@ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *g
/* Context activation is done by the caller. */
static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *gl_shader,
const struct wined3d_context_gl *context_gl, const struct wined3d_state *state)
struct wined3d_context_gl *context_gl, const struct wined3d_state *state)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_device *device = context_gl->c.device;
const struct wined3d_ivec4 *int_consts;
float position_fixup[4];
unsigned char i;
......@@ -596,14 +602,16 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g
if (!gl_shader->num_int_consts) return;
int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], &context_gl->c);
for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i)
{
if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED)
{
float val[4];
val[0] = (float)state->vs_consts_i[i].x;
val[1] = (float)state->vs_consts_i[i].y;
val[2] = (float)state->vs_consts_i[i].z;
val[0] = (float)int_consts[i].x;
val[1] = (float)int_consts[i].y;
val[2] = (float)int_consts[i].z;
val[3] = -1.0f;
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->int_consts[i], val));
......@@ -627,6 +635,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str
{
const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info;
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_device *device = context_gl->c.device;
if (!from_shader_select)
{
......@@ -670,8 +679,10 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str
const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog;
/* Load DirectX 9 float constants for vertex shader */
priv->highest_dirty_vs_const = shader_arb_load_constants_f(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
priv->highest_dirty_vs_const, state->vs_consts_f, priv->vshader_const_dirty);
priv->highest_dirty_vs_const = shader_arb_load_constants_f(vshader,
gl_info, GL_VERTEX_PROGRAM_ARB, priv->highest_dirty_vs_const,
wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F], &context_gl->c),
priv->vshader_const_dirty);
shader_arb_vs_local_constants(gl_shader, context_gl, state);
}
......@@ -682,8 +693,10 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str
UINT rt_height = state->fb.render_targets[0]->height;
/* Load DirectX 9 float constants for pixel shader */
priv->highest_dirty_ps_const = shader_arb_load_constants_f(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
priv->highest_dirty_ps_const, state->ps_consts_f, priv->pshader_const_dirty);
priv->highest_dirty_ps_const = shader_arb_load_constants_f(pshader,
gl_info, GL_FRAGMENT_PROGRAM_ARB, priv->highest_dirty_ps_const,
wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F], &context_gl->c),
priv->pshader_const_dirty);
shader_arb_ps_local_constants(gl_shader, context_gl, state, rt_height);
if (context_gl->c.constant_update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP)
......@@ -4406,14 +4419,20 @@ static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *sh
}
static void find_arb_ps_compile_args(const struct wined3d_state *state,
const struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader,
struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader,
struct arb_ps_compile_args *args)
{
const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info;
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_device *device = context_gl->c.device;
const struct wined3d_ivec4 *int_consts;
const BOOL *bool_consts;
int i;
WORD int_skip;
bool_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B], &context_gl->c);
int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], &context_gl->c);
find_ps_compile_args(state, shader, context_gl->c.stream_info.position_transformed, &args->super, &context_gl->c);
/* This forces all local boolean constants to 1 to make them stateblock independent */
......@@ -4421,7 +4440,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state,
for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i)
{
if (state->ps_consts_b[i])
if (bool_consts[i])
args->bools |= ( 1u << i);
}
......@@ -4454,24 +4473,29 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state,
}
else
{
args->loop_ctrl[i][0] = state->ps_consts_i[i].x;
args->loop_ctrl[i][1] = state->ps_consts_i[i].y;
args->loop_ctrl[i][2] = state->ps_consts_i[i].z;
args->loop_ctrl[i][0] = int_consts[i].x;
args->loop_ctrl[i][1] = int_consts[i].y;
args->loop_ctrl[i][2] = int_consts[i].z;
}
}
}
static void find_arb_vs_compile_args(const struct wined3d_state *state,
const struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader,
struct wined3d_context_gl *context_gl, const struct wined3d_shader *shader,
struct arb_vs_compile_args *args)
{
const struct wined3d_d3d_info *d3d_info = context_gl->c.d3d_info;
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
const struct wined3d_device *device = shader->device;
const struct wined3d_adapter *adapter = device->adapter;
const struct wined3d_ivec4 *int_consts;
const BOOL *bool_consts;
int i;
WORD int_skip;
bool_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B], &context_gl->c);
int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], &context_gl->c);
find_vs_compile_args(state, shader, &args->super, &context_gl->c);
args->clip.boolclip_compare = 0;
......@@ -4500,10 +4524,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
/* This forces all local boolean constants to 1 to make them stateblock independent */
args->clip.boolclip.bools = shader->reg_maps.local_bool_consts;
/* TODO: Figure out if it would be better to store bool constants as bitmasks in the stateblock */
for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i)
{
if (state->vs_consts_b[i])
if (bool_consts[i])
args->clip.boolclip.bools |= (1u << i);
}
......@@ -4531,9 +4554,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
}
else
{
args->loop_ctrl[i][0] = state->vs_consts_i[i].x;
args->loop_ctrl[i][1] = state->vs_consts_i[i].y;
args->loop_ctrl[i][2] = state->vs_consts_i[i].z;
args->loop_ctrl[i][0] = int_consts[i].x;
args->loop_ctrl[i][1] = int_consts[i].y;
args->loop_ctrl[i][2] = int_consts[i].z;
}
}
}
......
......@@ -667,7 +667,7 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
}
/* Context activation is done by the caller. */
BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context)
void *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context)
{
if (wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM))
buffer->resource.pin_sysmem = 1;
......
......@@ -4838,7 +4838,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context_gl *context_gl,
/* Immediate mode drawing can't make use of indices in a VBO - get the
* data from the index buffer. */
if (idx_size)
idx_data = wined3d_buffer_load_sysmem(state->index_buffer, &context_gl->c) + state->index_offset;
idx_data = (uint8_t *)wined3d_buffer_load_sysmem(state->index_buffer, &context_gl->c) + state->index_offset;
ops = &d3d_info->ffp_attrib_ops;
......
......@@ -416,7 +416,6 @@ struct wined3d_cs_push_constants
enum wined3d_push_constants type;
unsigned int start_idx;
unsigned int count;
BYTE constants[1];
};
struct wined3d_cs_reset_state
......@@ -2107,76 +2106,95 @@ void wined3d_device_context_emit_set_feature_level(struct wined3d_device_context
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
}
static const struct
static const struct push_constant_info
{
size_t offset;
size_t size;
unsigned int max_count;
DWORD mask;
}
wined3d_cs_push_constant_info[] =
{
/* WINED3D_PUSH_CONSTANTS_VS_F */
{FIELD_OFFSET(struct wined3d_state, vs_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_VS_F},
/* WINED3D_PUSH_CONSTANTS_PS_F */
{FIELD_OFFSET(struct wined3d_state, ps_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_PS_F},
/* WINED3D_PUSH_CONSTANTS_VS_I */
{FIELD_OFFSET(struct wined3d_state, vs_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_VS_I},
/* WINED3D_PUSH_CONSTANTS_PS_I */
{FIELD_OFFSET(struct wined3d_state, ps_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_PS_I},
/* WINED3D_PUSH_CONSTANTS_VS_B */
{FIELD_OFFSET(struct wined3d_state, vs_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_VS_B},
/* WINED3D_PUSH_CONSTANTS_PS_B */
{FIELD_OFFSET(struct wined3d_state, ps_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_PS_B},
[WINED3D_PUSH_CONSTANTS_VS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_VS_CONSTS_F, WINED3D_SHADER_CONST_VS_F},
[WINED3D_PUSH_CONSTANTS_PS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_PS_CONSTS_F, WINED3D_SHADER_CONST_PS_F},
[WINED3D_PUSH_CONSTANTS_VS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_CONST_VS_I},
[WINED3D_PUSH_CONSTANTS_PS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_CONST_PS_I},
[WINED3D_PUSH_CONSTANTS_VS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_CONST_VS_B},
[WINED3D_PUSH_CONSTANTS_PS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_CONST_PS_B},
};
static void wined3d_cs_st_push_constants(struct wined3d_device_context *context, enum wined3d_push_constants p,
unsigned int start_idx, unsigned int count, const void *constants)
static bool prepare_push_constant_buffer(struct wined3d_device *device, enum wined3d_push_constants type)
{
struct wined3d_cs *cs = wined3d_cs_from_context(context);
struct wined3d_device *device = cs->c.device;
unsigned int context_count;
unsigned int i;
size_t offset;
const struct push_constant_info *info = &wined3d_cs_push_constant_info[type];
HRESULT hr;
if (p == WINED3D_PUSH_CONSTANTS_VS_F)
device->shader_backend->shader_update_float_vertex_constants(device, start_idx, count);
else if (p == WINED3D_PUSH_CONSTANTS_PS_F)
device->shader_backend->shader_update_float_pixel_constants(device, start_idx, count);
const struct wined3d_buffer_desc desc =
{
.byte_width = info->max_count * info->size,
.bind_flags = 0,
.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W,
};
offset = wined3d_cs_push_constant_info[p].offset + start_idx * wined3d_cs_push_constant_info[p].size;
memcpy((BYTE *)&cs->state + offset, constants, count * wined3d_cs_push_constant_info[p].size);
for (i = 0, context_count = device->context_count; i < context_count; ++i)
if (!device->push_constants[type] && FAILED(hr = wined3d_buffer_create(device,
&desc, NULL, NULL, &wined3d_null_parent_ops, &device->push_constants[type])))
{
device->contexts[i]->constant_update_mask |= wined3d_cs_push_constant_info[p].mask;
ERR("Failed to create push constant buffer, hr %#lx.\n", hr);
return false;
}
return true;
}
static void wined3d_cs_exec_push_constants(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_cs_push_constants *op = data;
struct wined3d_device *device = cs->c.device;
unsigned int context_count, i;
/* The constant buffers were already updated; this op is just to mark the
* constants as invalid in the device state. */
wined3d_cs_st_push_constants(&cs->c, op->type, op->start_idx, op->count, op->constants);
if (op->type == WINED3D_PUSH_CONSTANTS_VS_F)
device->shader_backend->shader_update_float_vertex_constants(device, op->start_idx, op->count);
else if (op->type == WINED3D_PUSH_CONSTANTS_PS_F)
device->shader_backend->shader_update_float_pixel_constants(device, op->start_idx, op->count);
for (i = 0, context_count = device->context_count; i < context_count; ++i)
device->contexts[i]->constant_update_mask |= wined3d_cs_push_constant_info[op->type].mask;
}
static void wined3d_cs_mt_push_constants(struct wined3d_device_context *context, enum wined3d_push_constants p,
unsigned int start_idx, unsigned int count, const void *constants)
static void wined3d_device_context_emit_push_constants(struct wined3d_device_context *context,
enum wined3d_push_constants type, unsigned int start_idx, unsigned int count)
{
struct wined3d_cs *cs = wined3d_cs_from_context(context);
struct wined3d_cs_push_constants *op;
size_t size;
size = count * wined3d_cs_push_constant_info[p].size;
op = wined3d_device_context_require_space(&cs->c, FIELD_OFFSET(struct wined3d_cs_push_constants, constants[size]),
WINED3D_CS_QUEUE_DEFAULT);
op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_PUSH_CONSTANTS;
op->type = p;
op->type = type;
op->start_idx = start_idx;
op->count = count;
memcpy(op->constants, constants, size);
wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT);
}
void wined3d_device_context_push_constants(struct wined3d_device_context *context,
enum wined3d_push_constants type, unsigned int start_idx,
unsigned int count, const void *constants)
{
const struct push_constant_info *info = &wined3d_cs_push_constant_info[type];
unsigned int byte_offset = start_idx * info->size;
unsigned int byte_size = count * info->size;
struct wined3d_box box;
if (!prepare_push_constant_buffer(context->device, type))
return;
wined3d_box_set(&box, byte_offset, 0, byte_offset + byte_size, 1, 0, 1);
wined3d_device_context_emit_update_sub_resource(context,
&context->device->push_constants[type]->resource, 0, &box, constants, byte_size, byte_size);
wined3d_device_context_emit_push_constants(context, type, start_idx, count);
}
static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_device *device = cs->c.device;
......@@ -3145,7 +3163,6 @@ static const struct wined3d_device_context_ops wined3d_cs_st_ops =
wined3d_cs_st_require_space,
wined3d_cs_st_submit,
wined3d_cs_st_finish,
wined3d_cs_st_push_constants,
wined3d_cs_map_upload_bo,
wined3d_cs_unmap_upload_bo,
wined3d_cs_issue_query,
......@@ -3272,7 +3289,6 @@ static const struct wined3d_device_context_ops wined3d_cs_mt_ops =
wined3d_cs_mt_require_space,
wined3d_cs_mt_submit,
wined3d_cs_mt_finish,
wined3d_cs_mt_push_constants,
wined3d_cs_map_upload_bo,
wined3d_cs_unmap_upload_bo,
wined3d_cs_issue_query,
......@@ -4099,12 +4115,6 @@ static void wined3d_deferred_context_finish(struct wined3d_device_context *conte
ERR("Ignoring finish() on a deferred context.\n");
}
static void wined3d_deferred_context_push_constants(struct wined3d_device_context *context,
enum wined3d_push_constants p, unsigned int start_idx, unsigned int count, const void *constants)
{
FIXME("context %p, p %#x, start_idx %u, count %u, constants %p, stub!\n", context, p, start_idx, count, constants);
}
static struct wined3d_deferred_upload *deferred_context_get_upload(struct wined3d_deferred_context *deferred,
struct wined3d_resource *resource, unsigned int sub_resource_idx)
{
......@@ -4276,7 +4286,6 @@ static const struct wined3d_device_context_ops wined3d_deferred_context_ops =
wined3d_deferred_context_require_space,
wined3d_deferred_context_submit,
wined3d_deferred_context_finish,
wined3d_deferred_context_push_constants,
wined3d_deferred_context_map_upload_bo,
wined3d_deferred_context_unmap_upload_bo,
wined3d_deferred_context_issue_query,
......
......@@ -1178,18 +1178,24 @@ static void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info,
}
/* 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,
static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, struct wined3d_context_gl *context_gl,
struct wined3d_buffer *constant_buffer, const GLint *constant_locations, const struct constant_heap *heap,
unsigned char *stack, unsigned int version)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
const struct wined3d_shader_lconst *lconst;
/* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
if (shader->reg_maps.shader_version.major == 1
&& shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
else
walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
if (constant_buffer)
{
const struct wined3d_vec4 *constants = wined3d_buffer_load_sysmem(constant_buffer, &context_gl->c);
/* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
if (shader->reg_maps.shader_version.major == 1
&& shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
else
walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
}
if (!shader->load_local_constsF)
{
......@@ -1206,17 +1212,23 @@ static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, co
}
/* Context activation is done by the caller. */
static void shader_glsl_load_constants_i(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
const struct wined3d_ivec4 *constants, const GLint locations[WINED3D_MAX_CONSTS_I], uint32_t constants_set)
static void shader_glsl_load_constants_i(const struct wined3d_shader *shader, struct wined3d_context_gl *context_gl,
struct wined3d_buffer *constant_buffer, const GLint locations[WINED3D_MAX_CONSTS_I], uint32_t constants_set)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
unsigned int i;
struct list* ptr;
while (constants_set)
if (constant_buffer)
{
/* We found this uniform name in the program - go ahead and send the data */
i = wined3d_bit_scan(&constants_set);
GL_EXTCALL(glUniform4iv(locations[i], 1, &constants[i].x));
const struct wined3d_ivec4 *constants = wined3d_buffer_load_sysmem(constant_buffer, &context_gl->c);
while (constants_set)
{
/* We found this uniform name in the program - go ahead and send the data */
i = wined3d_bit_scan(&constants_set);
GL_EXTCALL(glUniform4iv(locations[i], 1, &constants[i].x));
}
}
/* Load immediate constants */
......@@ -1235,16 +1247,22 @@ static void shader_glsl_load_constants_i(const struct wined3d_shader *shader, co
}
/* Context activation is done by the caller. */
static void shader_glsl_load_constants_b(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
const BOOL *constants, const GLint locations[WINED3D_MAX_CONSTS_B], uint32_t constants_set)
static void shader_glsl_load_constants_b(const struct wined3d_shader *shader, struct wined3d_context_gl *context_gl,
struct wined3d_buffer *constant_buffer, const GLint locations[WINED3D_MAX_CONSTS_B], uint32_t constants_set)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
unsigned int i;
struct list* ptr;
while (constants_set)
if (constant_buffer)
{
i = wined3d_bit_scan(&constants_set);
GL_EXTCALL(glUniform1iv(locations[i], 1, &constants[i]));
const BOOL *constants = wined3d_buffer_load_sysmem(constant_buffer, &context_gl->c);
while (constants_set)
{
i = wined3d_bit_scan(&constants_set);
GL_EXTCALL(glUniform1iv(locations[i], 1, &constants[i]));
}
}
/* Load immediate constants */
......@@ -1520,6 +1538,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
float position_fixup[4 * WINED3D_MAX_VIEWPORTS];
struct wined3d_device *device = context->device;
struct shader_glsl_priv *priv = shader_priv;
unsigned int constant_version;
DWORD update_mask;
......@@ -1533,15 +1552,15 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
update_mask = context->constant_update_mask & prog->constant_update_mask;
if (update_mask & WINED3D_SHADER_CONST_VS_F)
shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f,
shader_glsl_load_constants_f(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F],
prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
if (update_mask & WINED3D_SHADER_CONST_VS_I)
shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i,
shader_glsl_load_constants_i(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I],
prog->vs.uniform_i_locations, vshader->reg_maps.integer_constants);
if (update_mask & WINED3D_SHADER_CONST_VS_B)
shader_glsl_load_constants_b(vshader, gl_info, state->vs_consts_b,
shader_glsl_load_constants_b(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B],
prog->vs.uniform_b_locations, vshader->reg_maps.boolean_constants);
if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES)
......@@ -1686,15 +1705,15 @@ 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,
shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F],
prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
if (update_mask & WINED3D_SHADER_CONST_PS_I)
shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i,
shader_glsl_load_constants_i(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I],
prog->ps.uniform_i_locations, pshader->reg_maps.integer_constants);
if (update_mask & WINED3D_SHADER_CONST_PS_B)
shader_glsl_load_constants_b(pshader, gl_info, state->ps_consts_b,
shader_glsl_load_constants_b(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B],
prog->ps.uniform_b_locations, pshader->reg_maps.boolean_constants);
if (update_mask & WINED3D_SHADER_CONST_PS_BUMP_ENV)
......
......@@ -2180,7 +2180,6 @@ static void wined3d_device_set_vs_consts_b(struct wined3d_device *device,
TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
memcpy(&device->cs->c.state->vs_consts_b[start_idx], constants, count * sizeof(*constants));
if (TRACE_ON(d3d))
{
for (i = 0; i < count; ++i)
......@@ -2197,7 +2196,6 @@ static void wined3d_device_set_vs_consts_i(struct wined3d_device *device,
TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
memcpy(&device->cs->c.state->vs_consts_i[start_idx], constants, count * sizeof(*constants));
if (TRACE_ON(d3d))
{
for (i = 0; i < count; ++i)
......@@ -2214,7 +2212,6 @@ static void wined3d_device_set_vs_consts_f(struct wined3d_device *device,
TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
memcpy(&device->cs->c.state->vs_consts_f[start_idx], constants, count * sizeof(*constants));
if (TRACE_ON(d3d))
{
for (i = 0; i < count; ++i)
......@@ -2231,7 +2228,6 @@ static void wined3d_device_set_ps_consts_b(struct wined3d_device *device,
TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
memcpy(&device->cs->c.state->ps_consts_b[start_idx], constants, count * sizeof(*constants));
if (TRACE_ON(d3d))
{
for (i = 0; i < count; ++i)
......@@ -2248,7 +2244,6 @@ static void wined3d_device_set_ps_consts_i(struct wined3d_device *device,
TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
memcpy(&device->cs->c.state->ps_consts_i[start_idx], constants, count * sizeof(*constants));
if (TRACE_ON(d3d))
{
for (i = 0; i < count; ++i)
......@@ -2265,7 +2260,6 @@ static void wined3d_device_set_ps_consts_f(struct wined3d_device *device,
TRACE("device %p, start_idx %u, count %u, constants %p.\n", device, start_idx, count, constants);
memcpy(&device->cs->c.state->ps_consts_f[start_idx], constants, count * sizeof(*constants));
if (TRACE_ON(d3d))
{
for (i = 0; i < count; ++i)
......
......@@ -3363,6 +3363,17 @@ void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size) DECLSPEC_HIDDEN;
enum wined3d_push_constants
{
WINED3D_PUSH_CONSTANTS_VS_F,
WINED3D_PUSH_CONSTANTS_PS_F,
WINED3D_PUSH_CONSTANTS_VS_I,
WINED3D_PUSH_CONSTANTS_PS_I,
WINED3D_PUSH_CONSTANTS_VS_B,
WINED3D_PUSH_CONSTANTS_PS_B,
WINED3D_PUSH_CONSTANTS_COUNT,
};
struct wined3d_blend_state
{
LONG refcount;
......@@ -3446,14 +3457,6 @@ struct wined3d_state
struct wined3d_shader_resource_view *shader_resource_view[WINED3D_SHADER_TYPE_COUNT][MAX_SHADER_RESOURCE_VIEWS];
struct wined3d_unordered_access_view *unordered_access_view[WINED3D_PIPELINE_COUNT][MAX_UNORDERED_ACCESS_VIEWS];
struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I];
BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS];
uint32_t sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
uint32_t texture_states[WINED3D_MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
......@@ -3594,6 +3597,8 @@ struct wined3d_device
/* Command stream */
struct wined3d_cs *cs;
struct wined3d_buffer *push_constants[WINED3D_PUSH_CONSTANTS_COUNT];
/* Context management */
struct wined3d_context **contexts;
UINT context_count;
......@@ -4425,16 +4430,6 @@ enum wined3d_cs_queue_id
WINED3D_CS_QUEUE_COUNT,
};
enum wined3d_push_constants
{
WINED3D_PUSH_CONSTANTS_VS_F,
WINED3D_PUSH_CONSTANTS_PS_F,
WINED3D_PUSH_CONSTANTS_VS_I,
WINED3D_PUSH_CONSTANTS_PS_I,
WINED3D_PUSH_CONSTANTS_VS_B,
WINED3D_PUSH_CONSTANTS_PS_B,
};
#define WINED3D_CS_QUERY_POLL_INTERVAL 10u
#if defined(_WIN64)
#define WINED3D_CS_QUEUE_SIZE 0x1000000u
......@@ -4457,8 +4452,6 @@ struct wined3d_device_context_ops
void *(*require_space)(struct wined3d_device_context *context, size_t size, enum wined3d_cs_queue_id queue_id);
void (*submit)(struct wined3d_device_context *context, enum wined3d_cs_queue_id queue_id);
void (*finish)(struct wined3d_device_context *context, enum wined3d_cs_queue_id queue_id);
void (*push_constants)(struct wined3d_device_context *context, enum wined3d_push_constants p,
unsigned int start_idx, unsigned int count, const void *constants);
bool (*map_upload_bo)(struct wined3d_device_context *context, struct wined3d_resource *resource,
unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc,
const struct wined3d_box *box, uint32_t flags);
......@@ -4542,12 +4535,6 @@ static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queu
cs->c.ops->finish(&cs->c, queue_id);
}
static inline void wined3d_device_context_push_constants(struct wined3d_device_context *context,
enum wined3d_push_constants p, unsigned int start_idx, unsigned int count, const void *constants)
{
context->ops->push_constants(context, p, start_idx, count, constants);
}
void wined3d_device_context_emit_blt_sub_resource(struct wined3d_device_context *context,
struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box,
struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box,
......@@ -4633,6 +4620,9 @@ void wined3d_device_context_emit_update_sub_resource(struct wined3d_device_conte
const void *data, unsigned int row_pitch, unsigned int slice_pitch) DECLSPEC_HIDDEN;
HRESULT wined3d_device_context_emit_unmap(struct wined3d_device_context *context,
struct wined3d_resource *resource, unsigned int sub_resource_idx) DECLSPEC_HIDDEN;
void wined3d_device_context_push_constants(struct wined3d_device_context *context,
enum wined3d_push_constants type, unsigned int start_idx,
unsigned int count, const void *constants) DECLSPEC_HIDDEN;
static inline void wined3d_resource_reference(struct wined3d_resource *resource)
{
......@@ -4741,7 +4731,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *
const struct wined3d_state *state) DECLSPEC_HIDDEN;
BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, uint32_t location) DECLSPEC_HIDDEN;
BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN;
void *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN;
BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location) DECLSPEC_HIDDEN;
void wined3d_buffer_update_sub_resource(struct wined3d_buffer *buffer, struct wined3d_context *context,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment