Module: wine Branch: master Commit: 165970992ae0ce2cd7ee352b48e793b0e93d03fc URL: http://source.winehq.org/git/wine.git/?a=commit;h=165970992ae0ce2cd7ee352b48...
Author: Alexander Dorofeyev alexd4@inbox.lv Date: Thu Mar 27 00:23:04 2008 +0200
wined3d: Make device palettes dynamically allocated.
---
dlls/wined3d/device.c | 72 ++++++++++++++++++++++++++++++++++++--- dlls/wined3d/stateblock.c | 12 ------- dlls/wined3d/wined3d_private.h | 6 ++-- 3 files changed, 69 insertions(+), 21 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index cfef9ac..74d3bf7 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2006,6 +2006,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR IWineD3DSwapChainImpl *swapchain = NULL; HRESULT hr; DWORD state; + unsigned int i;
TRACE("(%p)->(%p,%p)\n", This, pPresentationParameters, D3DCB_CreateAdditionalSwapChain); if(This->d3d_initialized) return WINED3DERR_INVALIDCALL; @@ -2035,6 +2036,25 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR This->fbo_color_attachments = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *) * GL_LIMITS(buffers)); This->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * GL_LIMITS(buffers));
+ This->NumberOfPalettes = 1; + This->palettes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PALETTEENTRY*)); + if(!This->palettes || !This->render_targets || !This->fbo_color_attachments || !This->draw_buffers) { + ERR("Out of memory!\n"); + goto err_out; + } + This->palettes[0] = HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY) * 256); + if(!This->palettes[0]) { + ERR("Out of memory!\n"); + goto err_out; + } + for (i = 0; i < 256; ++i) { + This->palettes[0][i].peRed = 0xFF; + This->palettes[0][i].peGreen = 0xFF; + This->palettes[0][i].peBlue = 0xFF; + This->palettes[0][i].peFlags = 0xFF; + } + This->currentPalette = 0; + /* Initialize the texture unit mapping to a 1:1 mapping */ for (state = 0; state < MAX_COMBINED_SAMPLERS; ++state) { if (state < GL_LIMITS(fragment_samplers)) { @@ -2157,6 +2177,11 @@ err_out: HeapFree(GetProcessHeap(), 0, This->draw_buffers); HeapFree(GetProcessHeap(), 0, This->swapchains); This->NumberOfSwapChains = 0; + if(This->palettes) { + HeapFree(GetProcessHeap(), 0, This->palettes[0]); + HeapFree(GetProcessHeap(), 0, This->palettes); + } + This->NumberOfPalettes = 0; if(swapchain) { IWineD3DSwapChain_Release( (IWineD3DSwapChain *) swapchain); } @@ -2275,6 +2300,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D This->swapchains = NULL; This->NumberOfSwapChains = 0;
+ for (i = 0; i < This->NumberOfPalettes; i++) HeapFree(GetProcessHeap(), 0, This->palettes[i]); + HeapFree(GetProcessHeap(), 0, This->palettes); + This->palettes = NULL; + This->NumberOfPalettes = 0; + HeapFree(GetProcessHeap(), 0, This->render_targets); HeapFree(GetProcessHeap(), 0, This->fbo_color_attachments); HeapFree(GetProcessHeap(), 0, This->draw_buffers); @@ -2282,7 +2312,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D This->fbo_color_attachments = NULL; This->draw_buffers = NULL;
- This->d3d_initialized = FALSE; return WINED3D_OK; } @@ -5452,11 +5481,38 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ValidateDevice(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_SetPaletteEntries(IWineD3DDevice *iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; int j; + UINT NewSize; + PALETTEENTRY **palettes; + TRACE("(%p) : PaletteNumber %u\n", This, PaletteNumber); + if (PaletteNumber >= MAX_PALETTES) { - WARN("(%p) : (%u) Out of range 0-%u, returning Invalid Call\n", This, PaletteNumber, MAX_PALETTES); + ERR("(%p) : (%u) Out of range 0-%u, returning Invalid Call\n", This, PaletteNumber, MAX_PALETTES); return WINED3DERR_INVALIDCALL; } + + if (PaletteNumber >= This->NumberOfPalettes) { + NewSize = This->NumberOfPalettes; + do { + NewSize *= 2; + } while(PaletteNumber >= NewSize); + palettes = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->palettes, sizeof(PALETTEENTRY*) * NewSize); + if (!palettes) { + ERR("Out of memory!\n"); + return E_OUTOFMEMORY; + } + This->palettes = palettes; + This->NumberOfPalettes = NewSize; + } + + if (!This->palettes[PaletteNumber]) { + This->palettes[PaletteNumber] = HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY) * 256); + if (!This->palettes[PaletteNumber]) { + ERR("Out of memory!\n"); + return E_OUTOFMEMORY; + } + } + for (j = 0; j < 256; ++j) { This->palettes[PaletteNumber][j].peRed = pEntries[j].peRed; This->palettes[PaletteNumber][j].peGreen = pEntries[j].peGreen; @@ -5471,8 +5527,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPaletteEntries(IWineD3DDevice *ifa IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; int j; TRACE("(%p) : PaletteNumber %u\n", This, PaletteNumber); - if (PaletteNumber >= MAX_PALETTES) { - WARN("(%p) : (%u) Out of range 0-%u, returning Invalid Call\n", This, PaletteNumber, MAX_PALETTES); + if (PaletteNumber >= This->NumberOfPalettes || !This->palettes[PaletteNumber]) { + /* What happens in such situation isn't documented; Native seems to silently abort + on such conditions. Return Invalid Call. */ + ERR("(%p) : (%u) Non-existent palette. NumberOfPalettes %u\n", This, PaletteNumber, This->NumberOfPalettes); return WINED3DERR_INVALIDCALL; } for (j = 0; j < 256; ++j) { @@ -5488,8 +5546,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPaletteEntries(IWineD3DDevice *ifa static HRESULT WINAPI IWineD3DDeviceImpl_SetCurrentTexturePalette(IWineD3DDevice *iface, UINT PaletteNumber) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; TRACE("(%p) : PaletteNumber %u\n", This, PaletteNumber); - if (PaletteNumber >= MAX_PALETTES) { - WARN("(%p) : (%u) Out of range 0-%u, returning Invalid Call\n", This, PaletteNumber, MAX_PALETTES); + /* Native appears to silently abort on attempt to make an uninitialized palette current and render. + (tested with reference rasterizer). Return Invalid Call. */ + if (PaletteNumber >= This->NumberOfPalettes || !This->palettes[PaletteNumber]) { + ERR("(%p) : (%u) Non-existent palette. NumberOfPalettes %u\n", This, PaletteNumber, This->NumberOfPalettes); return WINED3DERR_INVALIDCALL; } /*TODO: stateblocks */ diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index e81a8ed..cdcf969 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1239,18 +1239,6 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat This->textures[i] = NULL; }
- /* Defaulting palettes - Note these are device wide but reinitialized here for convenience*/ - for (i = 0; i < MAX_PALETTES; ++i) { - int j; - for (j = 0; j < 256; ++j) { - This->wineD3DDevice->palettes[i][j].peRed = 0xFF; - This->wineD3DDevice->palettes[i][j].peGreen = 0xFF; - This->wineD3DDevice->palettes[i][j].peBlue = 0xFF; - This->wineD3DDevice->palettes[i][j].peFlags = 0xFF; - } - } - This->wineD3DDevice->currentPalette = 0; - /* Set default GLSL program to NULL. We won't actually create one * until the app sets a vertex or pixel shader */ This->glsl_program = NULL; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3696183..0abeb1d 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -74,7 +74,7 @@ void hash_table_put(hash_table_t *table, void *key, void *value); void hash_table_remove(hash_table_t *table, void *key);
/* Device caps */ -#define MAX_PALETTES 256 +#define MAX_PALETTES 65536 #define MAX_STREAMS 16 #define MAX_TEXTURES 8 #define MAX_FRAGMENT_SAMPLERS 16 @@ -364,7 +364,6 @@ extern int num_lock; /* Maximum number of constants provided to the shaders */ #define HIGHEST_TRANSFORMSTATE 512 /* Highest value in WINED3DTRANSFORMSTATETYPE */ -#define MAX_PALETTES 256
/* Checking of API calls */ /* --------------------- */ @@ -834,7 +833,8 @@ struct IWineD3DDeviceImpl IWineD3DSwapChain *lastActiveSwapChain;
/* palettes texture management */ - PALETTEENTRY palettes[MAX_PALETTES][256]; + UINT NumberOfPalettes; + PALETTEENTRY **palettes; UINT currentPalette; UINT paletteConversionShader;