Commit d099dde7 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Track shader constants in the shader backend.

parent a14dab49
......@@ -226,6 +226,28 @@ static void shader_arb_load_constants(
}
}
static void shader_arb_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */
memset(This->activeContext->vshader_const_dirty + start, 1,
sizeof(*This->activeContext->vshader_const_dirty) * count);
This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count + 1);
}
static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */
memset(This->activeContext->pshader_const_dirty + start, 1,
sizeof(*This->activeContext->pshader_const_dirty) * count);
This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count + 1);
}
/* Generate the variable & register declarations for the ARB_vertex_program output target */
static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
......@@ -2175,6 +2197,8 @@ const shader_backend_t arb_program_shader_backend = {
shader_arb_select,
shader_arb_select_depth_blt,
shader_arb_deselect_depth_blt,
shader_arb_update_float_vertex_constants,
shader_arb_update_float_pixel_constants,
shader_arb_load_constants,
shader_arb_color_correction,
shader_arb_destroy,
......
......@@ -1122,6 +1122,8 @@ static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TAB
static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {}
static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
static void shader_none_color_correction(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup) {}
static void shader_none_destroy(IWineD3DBaseShader *iface) {}
......@@ -1169,6 +1171,8 @@ const shader_backend_t none_shader_backend = {
shader_none_select,
shader_none_select_depth_blt,
shader_none_deselect_depth_blt,
shader_none_update_float_vertex_constants,
shader_none_update_float_pixel_constants,
shader_none_load_constants,
shader_none_color_correction,
shader_none_destroy,
......
......@@ -3687,14 +3687,6 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
object->blitter = select_blit_implementation(Adapter, DeviceType);
/* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
* model can deal with that. It is essentially the same, just with adjusted
* Set*ShaderConstantF implementations
*/
if(object->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) object)) {
object->lpVtbl = &IWineD3DDevice_DirtyConst_Vtbl;
}
/* set the state of the device to valid */
object->state = WINED3D_OK;
......
......@@ -498,6 +498,50 @@ static void shader_glsl_load_constants(
}
}
static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
UINT i;
for (i = start; i < count + start; ++i)
{
if (!This->stateBlock->changed.vertexShaderConstantsF[i])
{
constants_entry *ptr = LIST_ENTRY(list_head(&This->stateBlock->set_vconstantsF),
constants_entry, entry);
if (!ptr || ptr->count >= sizeof(ptr->idx) / sizeof(*ptr->idx))
{
ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(constants_entry));
list_add_head(&This->stateBlock->set_vconstantsF, &ptr->entry);
}
ptr->idx[ptr->count++] = i;
}
}
}
static void shader_glsl_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
UINT i;
for (i = start; i < count + start; ++i)
{
if (!This->stateBlock->changed.pixelShaderConstantsF[i])
{
constants_entry *ptr = LIST_ENTRY(list_head(&This->stateBlock->set_pconstantsF),
constants_entry, entry);
if (!ptr || ptr->count >= sizeof(ptr->idx) / sizeof(*ptr->idx))
{
ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(constants_entry));
list_add_head(&This->stateBlock->set_pconstantsF, &ptr->entry);
}
ptr->idx[ptr->count++] = i;
}
}
}
/** Generate the variable & register declarations for the GLSL output target */
static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
......@@ -3866,6 +3910,8 @@ const shader_backend_t glsl_shader_backend = {
shader_glsl_select,
shader_glsl_select_depth_blt,
shader_glsl_deselect_depth_blt,
shader_glsl_update_float_vertex_constants,
shader_glsl_update_float_pixel_constants,
shader_glsl_load_constants,
shader_glsl_color_correction,
shader_glsl_destroy,
......
......@@ -432,6 +432,8 @@ typedef struct {
void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type);
void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count);
void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count);
void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
void (*shader_color_correction)(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup);
void (*shader_destroy)(IWineD3DBaseShader *iface);
......@@ -1146,7 +1148,7 @@ struct IWineD3DDeviceImpl
struct WineD3DRectPatch *currentPatch;
};
extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl, IWineD3DDevice_DirtyConst_Vtbl;
extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count,
CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color,
......
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