diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 4e959c4c510..dbffcb8ed82 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -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, diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 6567d7770b3..22897462675 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -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, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index de95c92d4f4..dc7017b213d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3593,61 +3593,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF( if (!This->isRecordingState) { - 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; - } - } - - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT); - } - - memset(This->updateStateBlock->changed.vertexShaderConstantsF + start, 1, - sizeof(*This->updateStateBlock->changed.vertexShaderConstantsF) * count); - - return WINED3D_OK; -} - -static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF_DirtyConst( -IWineD3DDevice *iface, -UINT start, -CONST float *srcData, -UINT count) { - - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - UINT i; - - TRACE("(iface %p, srcData %p, start %d, count %d)\n", - iface, srcData, start, count); - - /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */ - if (srcData == NULL || start + count > GL_LIMITS(vshader_constantsF) || start > GL_LIMITS(vshader_constantsF)) - return WINED3DERR_INVALIDCALL; - - memcpy(&This->updateStateBlock->vertexShaderConstantF[start * 4], srcData, count * sizeof(float) * 4); - if(TRACE_ON(d3d)) { - for (i = 0; i < count; i++) - TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", start + i, - srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]); - } - - if (!This->isRecordingState) - { - /* 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); - + This->shader_backend->shader_update_float_vertex_constants(iface, start, count); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT); } @@ -4040,61 +3986,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF( if (!This->isRecordingState) { - 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; - } - } - - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT); - } - - memset(This->updateStateBlock->changed.pixelShaderConstantsF + start, 1, - sizeof(*This->updateStateBlock->changed.pixelShaderConstantsF) * count); - - return WINED3D_OK; -} - -static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF_DirtyConst( - IWineD3DDevice *iface, - UINT start, - CONST float *srcData, - UINT count) { - - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - UINT i; - - TRACE("(iface %p, srcData %p, start %d, count %d)\n", - iface, srcData, start, count); - - /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */ - if (srcData == NULL || start + count > GL_LIMITS(pshader_constantsF) || start > GL_LIMITS(pshader_constantsF)) - return WINED3DERR_INVALIDCALL; - - memcpy(&This->updateStateBlock->pixelShaderConstantF[start * 4], srcData, count * sizeof(float) * 4); - if(TRACE_ON(d3d)) { - for (i = 0; i < count; i++) - TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", start + i, - srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]); - } - - if (!This->isRecordingState) - { - /* 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); - + This->shader_backend->shader_update_float_pixel_constants(iface, start, count); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT); } @@ -7635,149 +7527,6 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_EnumResources }; -const IWineD3DDeviceVtbl IWineD3DDevice_DirtyConst_Vtbl = -{ - /*** IUnknown methods ***/ - IWineD3DDeviceImpl_QueryInterface, - IWineD3DDeviceImpl_AddRef, - IWineD3DDeviceImpl_Release, - /*** IWineD3DDevice methods ***/ - IWineD3DDeviceImpl_GetParent, - /*** Creation methods**/ - IWineD3DDeviceImpl_CreateVertexBuffer, - IWineD3DDeviceImpl_CreateIndexBuffer, - IWineD3DDeviceImpl_CreateStateBlock, - IWineD3DDeviceImpl_CreateSurface, - IWineD3DDeviceImpl_CreateTexture, - IWineD3DDeviceImpl_CreateVolumeTexture, - IWineD3DDeviceImpl_CreateVolume, - IWineD3DDeviceImpl_CreateCubeTexture, - IWineD3DDeviceImpl_CreateQuery, - IWineD3DDeviceImpl_CreateSwapChain, - IWineD3DDeviceImpl_CreateVertexDeclaration, - IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF, - IWineD3DDeviceImpl_CreateVertexShader, - IWineD3DDeviceImpl_CreatePixelShader, - IWineD3DDeviceImpl_CreatePalette, - /*** Odd functions **/ - IWineD3DDeviceImpl_Init3D, - IWineD3DDeviceImpl_InitGDI, - IWineD3DDeviceImpl_Uninit3D, - IWineD3DDeviceImpl_UninitGDI, - IWineD3DDeviceImpl_SetMultithreaded, - IWineD3DDeviceImpl_EvictManagedResources, - IWineD3DDeviceImpl_GetAvailableTextureMem, - IWineD3DDeviceImpl_GetBackBuffer, - IWineD3DDeviceImpl_GetCreationParameters, - IWineD3DDeviceImpl_GetDeviceCaps, - IWineD3DDeviceImpl_GetDirect3D, - IWineD3DDeviceImpl_GetDisplayMode, - IWineD3DDeviceImpl_SetDisplayMode, - IWineD3DDeviceImpl_GetNumberOfSwapChains, - IWineD3DDeviceImpl_GetRasterStatus, - IWineD3DDeviceImpl_GetSwapChain, - IWineD3DDeviceImpl_Reset, - IWineD3DDeviceImpl_SetDialogBoxMode, - IWineD3DDeviceImpl_SetCursorProperties, - IWineD3DDeviceImpl_SetCursorPosition, - IWineD3DDeviceImpl_ShowCursor, - IWineD3DDeviceImpl_TestCooperativeLevel, - /*** Getters and setters **/ - IWineD3DDeviceImpl_SetClipPlane, - IWineD3DDeviceImpl_GetClipPlane, - IWineD3DDeviceImpl_SetClipStatus, - IWineD3DDeviceImpl_GetClipStatus, - IWineD3DDeviceImpl_SetCurrentTexturePalette, - IWineD3DDeviceImpl_GetCurrentTexturePalette, - IWineD3DDeviceImpl_SetDepthStencilSurface, - IWineD3DDeviceImpl_GetDepthStencilSurface, - IWineD3DDeviceImpl_SetGammaRamp, - IWineD3DDeviceImpl_GetGammaRamp, - IWineD3DDeviceImpl_SetIndices, - IWineD3DDeviceImpl_GetIndices, - IWineD3DDeviceImpl_SetBaseVertexIndex, - IWineD3DDeviceImpl_GetBaseVertexIndex, - IWineD3DDeviceImpl_SetLight, - IWineD3DDeviceImpl_GetLight, - IWineD3DDeviceImpl_SetLightEnable, - IWineD3DDeviceImpl_GetLightEnable, - IWineD3DDeviceImpl_SetMaterial, - IWineD3DDeviceImpl_GetMaterial, - IWineD3DDeviceImpl_SetNPatchMode, - IWineD3DDeviceImpl_GetNPatchMode, - IWineD3DDeviceImpl_SetPaletteEntries, - IWineD3DDeviceImpl_GetPaletteEntries, - IWineD3DDeviceImpl_SetPixelShader, - IWineD3DDeviceImpl_GetPixelShader, - IWineD3DDeviceImpl_SetPixelShaderConstantB, - IWineD3DDeviceImpl_GetPixelShaderConstantB, - IWineD3DDeviceImpl_SetPixelShaderConstantI, - IWineD3DDeviceImpl_GetPixelShaderConstantI, - IWineD3DDeviceImpl_SetPixelShaderConstantF_DirtyConst, - IWineD3DDeviceImpl_GetPixelShaderConstantF, - IWineD3DDeviceImpl_SetRenderState, - IWineD3DDeviceImpl_GetRenderState, - IWineD3DDeviceImpl_SetRenderTarget, - IWineD3DDeviceImpl_GetRenderTarget, - IWineD3DDeviceImpl_SetFrontBackBuffers, - IWineD3DDeviceImpl_SetSamplerState, - IWineD3DDeviceImpl_GetSamplerState, - IWineD3DDeviceImpl_SetScissorRect, - IWineD3DDeviceImpl_GetScissorRect, - IWineD3DDeviceImpl_SetSoftwareVertexProcessing, - IWineD3DDeviceImpl_GetSoftwareVertexProcessing, - IWineD3DDeviceImpl_SetStreamSource, - IWineD3DDeviceImpl_GetStreamSource, - IWineD3DDeviceImpl_SetStreamSourceFreq, - IWineD3DDeviceImpl_GetStreamSourceFreq, - IWineD3DDeviceImpl_SetTexture, - IWineD3DDeviceImpl_GetTexture, - IWineD3DDeviceImpl_SetTextureStageState, - IWineD3DDeviceImpl_GetTextureStageState, - IWineD3DDeviceImpl_SetTransform, - IWineD3DDeviceImpl_GetTransform, - IWineD3DDeviceImpl_SetVertexDeclaration, - IWineD3DDeviceImpl_GetVertexDeclaration, - IWineD3DDeviceImpl_SetVertexShader, - IWineD3DDeviceImpl_GetVertexShader, - IWineD3DDeviceImpl_SetVertexShaderConstantB, - IWineD3DDeviceImpl_GetVertexShaderConstantB, - IWineD3DDeviceImpl_SetVertexShaderConstantI, - IWineD3DDeviceImpl_GetVertexShaderConstantI, - IWineD3DDeviceImpl_SetVertexShaderConstantF_DirtyConst, - IWineD3DDeviceImpl_GetVertexShaderConstantF, - IWineD3DDeviceImpl_SetViewport, - IWineD3DDeviceImpl_GetViewport, - IWineD3DDeviceImpl_MultiplyTransform, - IWineD3DDeviceImpl_ValidateDevice, - IWineD3DDeviceImpl_ProcessVertices, - /*** State block ***/ - IWineD3DDeviceImpl_BeginStateBlock, - IWineD3DDeviceImpl_EndStateBlock, - /*** Scene management ***/ - IWineD3DDeviceImpl_BeginScene, - IWineD3DDeviceImpl_EndScene, - IWineD3DDeviceImpl_Present, - IWineD3DDeviceImpl_Clear, - /*** Drawing ***/ - IWineD3DDeviceImpl_DrawPrimitive, - IWineD3DDeviceImpl_DrawIndexedPrimitive, - IWineD3DDeviceImpl_DrawPrimitiveUP, - IWineD3DDeviceImpl_DrawIndexedPrimitiveUP, - IWineD3DDeviceImpl_DrawPrimitiveStrided, - IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided, - IWineD3DDeviceImpl_DrawRectPatch, - IWineD3DDeviceImpl_DrawTriPatch, - IWineD3DDeviceImpl_DeletePatch, - IWineD3DDeviceImpl_ColorFill, - IWineD3DDeviceImpl_UpdateTexture, - IWineD3DDeviceImpl_UpdateSurface, - IWineD3DDeviceImpl_GetFrontBufferData, - /*** object tracking ***/ - IWineD3DDeviceImpl_ResourceReleased, - IWineD3DDeviceImpl_EnumResources -}; - const DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = { WINED3DRS_ALPHABLENDENABLE , WINED3DRS_ALPHAFUNC , diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index d8ec3efa87c..fb7869a0f96 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -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; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 0c745357e68..205f1111284 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -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, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8ff9814c0e0..195af9fedae 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -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,