From: Kamil Hornicek Date: Sun, 15 Feb 2009 14:01:23 +0000 (+0000) Subject: - update wined3d/d3d8/d3d9 to Wine 1.1.15 X-Git-Tag: backups/danny-web@40415~24^2~472 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=43961e394ed234020b29300a12e32759f78a8ad7 - update wined3d/d3d8/d3d9 to Wine 1.1.15 svn path=/trunk/; revision=39607 --- diff --git a/reactos/dll/directx/wine/d3d8/device.c b/reactos/dll/directx/wine/d3d8/device.c index 5ef6311d6c2..9e3fb6986e4 100644 --- a/reactos/dll/directx/wine/d3d8/device.c +++ b/reactos/dll/directx/wine/d3d8/device.c @@ -2265,19 +2265,19 @@ static inline struct IDirect3DDevice8Impl *device_from_device_parent(IWineD3DDev - FIELD_OFFSET(struct IDirect3DDevice8Impl, device_parent_vtbl)); } -HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object) +static HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object) { struct IDirect3DDevice8Impl *This = device_from_device_parent(iface); return IDirect3DDevice8Impl_QueryInterface((IDirect3DDevice8 *)This, riid, object); } -ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface) +static ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface) { struct IDirect3DDevice8Impl *This = device_from_device_parent(iface); return IDirect3DDevice8Impl_AddRef((IDirect3DDevice8 *)This); } -ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface) +static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface) { struct IDirect3DDevice8Impl *This = device_from_device_parent(iface); return IDirect3DDevice8Impl_Release((IDirect3DDevice8 *)This); diff --git a/reactos/dll/directx/wine/d3d9/device.c b/reactos/dll/directx/wine/d3d9/device.c index 768bf9d1053..b68caab75d7 100644 --- a/reactos/dll/directx/wine/d3d9/device.c +++ b/reactos/dll/directx/wine/d3d9/device.c @@ -265,7 +265,7 @@ static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX ifac } static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) { - BOOL *resources_ok = (BOOL *) data; + BOOL *resources_ok = data; WINED3DRESOURCETYPE type; HRESULT ret = S_OK; WINED3DSURFACE_DESC surface_desc; @@ -617,7 +617,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(LPDIRECT3DDEVICE9EX ifa TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DSurface_Blt(dst->wineD3DSurface, (RECT *) pDestRect, src->wineD3DSurface, (RECT *) pSourceRect, 0, NULL, Filter); + hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -1338,7 +1338,7 @@ static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; - HRESULT hr; + HRESULT hr = S_OK; TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d9_cs); diff --git a/reactos/dll/directx/wine/d3d9/directx.c b/reactos/dll/directx/wine/d3d9/directx.c index 36db33b21de..bd9ba591307 100644 --- a/reactos/dll/directx/wine/d3d9/directx.c +++ b/reactos/dll/directx/wine/d3d9/directx.c @@ -37,7 +37,7 @@ static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9EX iface, REFIID return S_OK; } else if(IsEqualGUID(riid, &IID_IDirect3D9Ex)) { if(This->extended) { - *ppobj = (IDirect3D9Ex *) This; + *ppobj = This; TRACE("Returning IDirect3D9Ex interface at %p\n", *ppobj); IDirect3D9Ex_AddRef((IDirect3D9Ex *)*ppobj); } else { diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index 7ff3cd4467b..6bc152abdfd 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -510,7 +510,7 @@ static void vshader_program_add_param(const SHADER_OPCODE_ARG *arg, const DWORD break; case WINED3DSPR_INPUT: - if (This->swizzle_map & (1 << reg)) is_color = TRUE; + if (This->cur_args->swizzle_map & (1 << reg)) is_color = TRUE; sprintf(tmpReg, "vertex.attrib[%u]", reg); strcat(hwLine, tmpReg); @@ -1741,18 +1741,19 @@ static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, en static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv; + struct shader_arb_priv *priv = This->shader_priv; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; if (useVS) { - TRACE("Using vertex shader\n"); - IWineD3DVertexShaderImpl_CompileShader(This->stateBlock->vertexShader); + struct vs_compile_args compile_args; - priv->current_vprogram_id = ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->prgId; + TRACE("Using vertex shader\n"); + find_vs_compile_args((IWineD3DVertexShaderImpl *) This->stateBlock->vertexShader, This->stateBlock, &compile_args); + priv->current_vprogram_id = find_gl_vshader((IWineD3DVertexShaderImpl *) This->stateBlock->vertexShader, &compile_args); /* Bind the vertex program */ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id)); - checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);"); + checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);"); /* Enable OpenGL vertex programs */ glEnable(GL_VERTEX_PROGRAM_ARB); @@ -1773,7 +1774,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { /* Bind the fragment program */ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id)); - checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);"); + checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id);"); if(!priv->use_arbfp_fixed_func) { /* Enable OpenGL fragment programs */ @@ -1794,7 +1795,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv; + struct shader_arb_priv *priv = This->shader_priv; GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type]; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; @@ -1809,7 +1810,7 @@ static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types te static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv; + struct shader_arb_priv *priv = This->shader_priv; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; if (priv->current_vprogram_id) { @@ -1857,16 +1858,22 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) { HeapFree(GetProcessHeap(), 0, This->gl_shaders); This->gl_shaders = NULL; This->num_gl_shaders = 0; + This->shader_array_size = 0; } else { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface; + UINT i; ENTER_GL(); - GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId)); - checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId))"); - ((IWineD3DVertexShaderImpl *) This)->prgId = 0; + for(i = 0; i < This->num_gl_shaders; i++) { + GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId)); + checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))"); + } LEAVE_GL(); + HeapFree(GetProcessHeap(), 0, This->gl_shaders); + This->gl_shaders = NULL; + This->num_gl_shaders = 0; + This->shader_array_size = 0; } - baseShader->baseShader.is_compiled = FALSE; } static HRESULT shader_arb_alloc(IWineD3DDevice *iface) { @@ -1878,7 +1885,7 @@ static HRESULT shader_arb_alloc(IWineD3DDevice *iface) { static void shader_arb_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; - struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv; + struct shader_arb_priv *priv = This->shader_priv; int i; if(priv->depth_blt_vprogram_id) { @@ -2007,13 +2014,14 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF return retval; } -static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) { +static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; const shader_reg_maps *reg_maps = &This->baseShader.reg_maps; CONST DWORD *function = This->baseShader.function; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device; const WineD3D_GL_Info *gl_info = &device->adapter->gl_info; const local_constant *lconst; + GLuint ret; /* Create the hw ARB shader */ shader_addline(buffer, "!!ARBvp1.0\n"); @@ -2060,9 +2068,16 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF /* Base Shader Body */ shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function); - /* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */ - if (!reg_maps->fog) + /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used + * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE), + * the fog frag coord is thrown away. If the fog frag coord is used, but not written by + * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0) + */ + if(args->fog_src == VS_FOG_Z) { shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n"); + } else if (!reg_maps->fog) { + shader_addline(buffer, "MOV result.fogcoord, 0.0;\n"); + } /* Write the final position. * @@ -2085,12 +2100,12 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF shader_addline(buffer, "END\n"); /* TODO: change to resource.glObjectHandle or something like that */ - GL_EXTCALL(glGenProgramsARB(1, &This->prgId)); + GL_EXTCALL(glGenProgramsARB(1, &ret)); - TRACE("Creating a hw vertex shader, prg=%d\n", This->prgId); - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->prgId)); + TRACE("Creating a hw vertex shader, prg=%d\n", ret); + GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ret)); - TRACE("Created hw vertex shader, prg=%d\n", This->prgId); + TRACE("Created hw vertex shader, prg=%d\n", ret); /* Create the program and check for errors */ GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, buffer->bsize, buffer->buffer)); @@ -2100,16 +2115,17 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); FIXME("HW VertexShader Error at position %d: %s\n", errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB))); - This->prgId = -1; - } - - /* Load immediate constants */ - if(!This->baseShader.load_local_constsF) { - LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { - const float *value = (const float *)lconst->value; - GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value)); + ret = -1; + } else { + /* Load immediate constants */ + if(!This->baseShader.load_local_constsF) { + LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { + const float *value = (const float *)lconst->value; + GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value)); + } } } + return ret; } static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps) @@ -2294,7 +2310,7 @@ static HRESULT arbfp_alloc(IWineD3DDevice *iface) { This->fragment_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_arb_priv)); if(!This->fragment_priv) return E_OUTOFMEMORY; } - priv = (struct shader_arb_priv *) This->fragment_priv; + priv = This->fragment_priv; priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare); priv->use_arbfp_fixed_func = TRUE; return WINED3D_OK; @@ -2313,7 +2329,7 @@ static void arbfp_free_ffpshader(void *value, void *gli) { static void arbfp_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - struct shader_arb_priv *priv = (struct shader_arb_priv *) This->fragment_priv; + struct shader_arb_priv *priv = This->fragment_priv; hash_table_destroy(priv->fragment_shaders, arbfp_free_ffpshader, &This->adapter->gl_info); priv->use_arbfp_fixed_func = FALSE; @@ -2952,7 +2968,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; - struct shader_arb_priv *priv = (struct shader_arb_priv *) device->fragment_priv; + struct shader_arb_priv *priv = device->fragment_priv; BOOL use_pshader = use_ps(stateblock); BOOL use_vshader = use_vs(stateblock); struct ffp_frag_settings settings; @@ -3051,22 +3067,17 @@ static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, Win if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return; - if(use_vs(stateblock) - && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) { - if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) { - FIXME("vertex shader with table fog used\n"); - } - context->last_was_foggy_shader = TRUE; - new_source = FOGSOURCE_VS; - } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { - context->last_was_foggy_shader = FALSE; - if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) { - new_source = FOGSOURCE_COORD; + if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { + if(use_vs(stateblock)) { + new_source = FOGSOURCE_VS; } else { - new_source = FOGSOURCE_FFP; + if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) { + new_source = FOGSOURCE_COORD; + } else { + new_source = FOGSOURCE_FFP; + } } } else { - context->last_was_foggy_shader = FALSE; new_source = FOGSOURCE_FFP; } if(new_source != context->fog_source) { @@ -3263,7 +3274,7 @@ static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) { } static void arbfp_blit_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; - struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv; + struct arbfp_blit_priv *priv = device->blit_priv; ENTER_GL(); GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_rect_shader)); @@ -3514,7 +3525,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu GLenum shader; SHADER_BUFFER buffer; char luminance_component; - struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv; + struct arbfp_blit_priv *priv = device->blit_priv; /* Shader header */ shader_buffer_init(&buffer); @@ -3649,7 +3660,7 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum t GLenum shader; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; float size[4] = {width, height, 1, 1}; - struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv; + struct arbfp_blit_priv *priv = device->blit_priv; const struct GlPixelFormatDesc *glDesc; enum yuv_fixup yuv_fixup; diff --git a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c index c01ec1aee21..4fe543045fc 100644 --- a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -803,7 +803,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi IWineD3DDeviceImpl *This = stateblock->wineD3DDevice; const struct atifs_ffp_desc *desc; struct ffp_frag_settings settings; - struct atifs_private_data *priv = (struct atifs_private_data *) This->fragment_priv; + struct atifs_private_data *priv = This->fragment_priv; DWORD mapped_stage; unsigned int i; @@ -1107,7 +1107,7 @@ static HRESULT atifs_alloc(IWineD3DDevice *iface) { ERR("Out of memory\n"); return E_OUTOFMEMORY; } - priv = (struct atifs_private_data *) This->fragment_priv; + priv = This->fragment_priv; priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare); return WINED3D_OK; } @@ -1126,7 +1126,7 @@ static void atifs_free_ffpshader(void *value, void *device) { static void atifs_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - struct atifs_private_data *priv = (struct atifs_private_data *) This->fragment_priv; + struct atifs_private_data *priv = This->fragment_priv; hash_table_destroy(priv->fragment_shaders, atifs_free_ffpshader, This); diff --git a/reactos/dll/directx/wine/wined3d/baseshader.c b/reactos/dll/directx/wine/wined3d/baseshader.c index a270b0c49cb..f191b2c26fa 100644 --- a/reactos/dll/directx/wine/wined3d/baseshader.c +++ b/reactos/dll/directx/wine/wined3d/baseshader.c @@ -31,8 +31,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define GLNAME_REQUIRE_GLSL ((const char *)1) - static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version); static inline BOOL shader_is_version_token(DWORD token) { @@ -1135,8 +1133,9 @@ static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU FIXME("NONE shader backend asked to generate a pixel shader\n"); return 0; } -static void shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) { +static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { FIXME("NONE shader backend asked to generate a vertex shader\n"); + return 0; } #define GLINFO_LOCATION (*gl_info) diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index d4a57c9eec3..71e69e30298 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -2104,7 +2104,7 @@ static void IWineD3DDeviceImpl_LoadLogo(IWineD3DDeviceImpl *This, const char *fi HDC dcb = NULL, dcs = NULL; WINEDDCOLORKEY colorkey; - hbm = (HBITMAP) LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); + hbm = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); if(hbm) { GetObjectA(hbm, sizeof(BITMAP), &bm); @@ -6765,7 +6765,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i { const struct GlPixelFormatDesc *glDesc; const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(WINED3DFMT_A8R8G8B8, &GLINFO_LOCATION, &glDesc); - char *mem, *bits = (char *)rect.pBits; + char *mem, *bits = rect.pBits; GLint intfmt = glDesc->glInternal; GLint format = glDesc->glFormat; GLint type = glDesc->glType; diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index a78f4e5c74b..dcd18a87952 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -1287,6 +1287,12 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { gl_info->gl_card = CARD_ATI_RADEON_X700; vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */ } + /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */ + else if(strstr(gl_info->gl_renderer, "Radeon Xpress")) + { + gl_info->gl_card = CARD_ATI_RADEON_XPRESS_200M; + vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */ + } /* Radeon R3xx */ else { gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */ diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index b78078fd85a..37f43b4a3b2 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -324,8 +324,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory; } - if (idxSize == 2) pIdxBufS = (const WORD *) idxData; - else pIdxBufL = (const DWORD *) idxData; + if (idxSize == 2) pIdxBufS = idxData; + else pIdxBufL = idxData; } else if (idxData) { ERR("non-NULL idxData with 0 idxSize, this should never happen\n"); return; @@ -519,31 +519,41 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, const UINT index, const void *ptr) { switch(type) { case WINED3DDECLTYPE_FLOAT1: - GL_EXTCALL(glVertexAttrib1fvARB(index, (const float *)ptr)); + GL_EXTCALL(glVertexAttrib1fvARB(index, ptr)); break; case WINED3DDECLTYPE_FLOAT2: - GL_EXTCALL(glVertexAttrib2fvARB(index, (const float *)ptr)); + GL_EXTCALL(glVertexAttrib2fvARB(index, ptr)); break; case WINED3DDECLTYPE_FLOAT3: - GL_EXTCALL(glVertexAttrib3fvARB(index, (const float *)ptr)); + GL_EXTCALL(glVertexAttrib3fvARB(index, ptr)); break; case WINED3DDECLTYPE_FLOAT4: - GL_EXTCALL(glVertexAttrib4fvARB(index, (const float *)ptr)); + GL_EXTCALL(glVertexAttrib4fvARB(index, ptr)); break; case WINED3DDECLTYPE_UBYTE4: GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr)); break; - case WINED3DDECLTYPE_UBYTE4N: case WINED3DDECLTYPE_D3DCOLOR: + if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA)) + { + const DWORD *src = ptr; + DWORD c = *src & 0xff00ff00; + c |= (*src & 0xff0000) >> 16; + c |= (*src & 0xff) << 16; + GL_EXTCALL(glVertexAttrib4NubvARB(index, (GLubyte *)&c)); + break; + } + /* else fallthrough */ + case WINED3DDECLTYPE_UBYTE4N: GL_EXTCALL(glVertexAttrib4NubvARB(index, ptr)); break; case WINED3DDECLTYPE_SHORT2: - GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr)); + GL_EXTCALL(glVertexAttrib4svARB(index, ptr)); break; case WINED3DDECLTYPE_SHORT4: - GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr)); + GL_EXTCALL(glVertexAttrib4svARB(index, ptr)); break; case WINED3DDECLTYPE_SHORT2N: @@ -559,10 +569,10 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co break; } case WINED3DDECLTYPE_SHORT4N: - GL_EXTCALL(glVertexAttrib4NsvARB(index, (const GLshort *)ptr)); + GL_EXTCALL(glVertexAttrib4NsvARB(index, ptr)); break; case WINED3DDECLTYPE_USHORT4N: - GL_EXTCALL(glVertexAttrib4NusvARB(index, (const GLushort *)ptr)); + GL_EXTCALL(glVertexAttrib4NusvARB(index, ptr)); break; case WINED3DDECLTYPE_UDEC3: @@ -579,7 +589,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co * byte float according to the IEEE standard */ if (GL_SUPPORT(NV_HALF_FLOAT)) { - GL_EXTCALL(glVertexAttrib2hvNV(index, (const GLhalfNV *)ptr)); + GL_EXTCALL(glVertexAttrib2hvNV(index, ptr)); } else { float x = float_16_to_32(((const unsigned short *)ptr) + 0); float y = float_16_to_32(((const unsigned short *)ptr) + 1); @@ -588,7 +598,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co break; case WINED3DDECLTYPE_FLOAT16_4: if (GL_SUPPORT(NV_HALF_FLOAT)) { - GL_EXTCALL(glVertexAttrib4hvNV(index, (const GLhalfNV *)ptr)); + GL_EXTCALL(glVertexAttrib4hvNV(index, ptr)); } else { float x = float_16_to_32(((const unsigned short *)ptr) + 0); float y = float_16_to_32(((const unsigned short *)ptr) + 1); @@ -626,8 +636,8 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStr idxData = ((IWineD3DIndexBufferImpl *) stateblock->pIndexData)->resource.allocatedMemory; } - if (idxSize == 2) pIdxBufS = (const WORD *) idxData; - else pIdxBufL = (const DWORD *) idxData; + if (idxSize == 2) pIdxBufS = idxData; + else pIdxBufL = idxData; } else if (idxData) { ERR("non-NULL idxData with 0 idxSize, this should never happen\n"); return; @@ -954,7 +964,7 @@ void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives, sprintf(buffer, "/tmp/texture_%p_%ld_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo); TRACE("Saving texture %s\n", buffer); if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) { - IWineD3DTexture_GetSurfaceLevel((IWineD3DTexture *)This->stateBlock->textures[textureNo], 0, &pSur); + IWineD3DTexture_GetSurfaceLevel(This->stateBlock->textures[textureNo], 0, &pSur); IWineD3DSurface_SaveSnapshot(pSur, buffer); IWineD3DSurface_Release(pSur); } else { diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index 8dfb416e206..23beb4620bc 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -101,16 +101,18 @@ struct glsl_shader_prog_link { GLhandleARB luminanceoffset_location[MAX_TEXTURES]; GLhandleARB ycorrection_location; GLenum vertex_color_clamp; - GLhandleARB vshader; + IWineD3DVertexShader *vshader; IWineD3DPixelShader *pshader; + struct vs_compile_args vs_args; struct ps_compile_args ps_args; UINT constant_version; }; typedef struct { - GLhandleARB vshader; + IWineD3DVertexShader *vshader; IWineD3DPixelShader *pshader; struct ps_compile_args ps_args; + struct vs_compile_args vs_args; } glsl_program_key_t; @@ -471,7 +473,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine static void reset_program_constant_version(void *value, void *context) { - struct glsl_shader_prog_link *entry = (struct glsl_shader_prog_link *)value; + struct glsl_shader_prog_link *entry = value; entry->constant_version = 0; } @@ -484,7 +486,7 @@ static void shader_glsl_load_constants( char useVertexShader) { IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *)deviceImpl->shader_priv; + struct shader_glsl_priv *priv = deviceImpl->shader_priv; IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock; const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info; @@ -621,7 +623,7 @@ static inline void update_heap_entry(struct constant_heap *heap, unsigned int id static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv; + struct shader_glsl_priv *priv = This->shader_priv; struct constant_heap *heap = &priv->vconst_heap; UINT i; @@ -637,7 +639,7 @@ static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UIN static void shader_glsl_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv; + struct shader_glsl_priv *priv = This->shader_priv; struct constant_heap *heap = &priv->pconst_heap; UINT i; @@ -1030,7 +1032,7 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to strcpy(tmpStr, "gl_SecondaryColor"); } } else { - if (((IWineD3DVertexShaderImpl *)This)->swizzle_map & (1 << reg)) *is_color = TRUE; + if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg)) *is_color = TRUE; sprintf(tmpStr, "attrib%u", reg); } break; @@ -2918,20 +2920,23 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t)); key->vshader = entry->vshader; key->pshader = entry->pshader; + key->vs_args = entry->vs_args; key->ps_args = entry->ps_args; hash_table_put(priv->glsl_program_lookup, key, entry); } static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv, - GLhandleARB vshader, IWineD3DPixelShader *pshader, struct ps_compile_args *ps_args) { + IWineD3DVertexShader *vshader, IWineD3DPixelShader *pshader, struct vs_compile_args *vs_args, + struct ps_compile_args *ps_args) { glsl_program_key_t key; key.vshader = vshader; key.pshader = pshader; + key.vs_args = *vs_args; key.ps_args = *ps_args; - return (struct glsl_shader_prog_link *)hash_table_get(priv->glsl_program_lookup, &key); + return hash_table_get(priv->glsl_program_lookup, &key); } static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD3D_GL_Info *gl_info, @@ -2942,6 +2947,7 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t)); key->vshader = entry->vshader; key->pshader = entry->pshader; + key->vs_args = entry->vs_args; key->ps_args = entry->ps_args; hash_table_remove(priv->glsl_program_lookup, key); @@ -3248,7 +3254,7 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)"); GL_EXTCALL(glShaderSourceARB(ret, 1, (const char**)&buffer.buffer, NULL)); - checkGLcall("glShaderSourceARB(ret, 1, (const char**)&buffer.buffer, NULL)"); + checkGLcall("glShaderSourceARB(ret, 1, &buffer.buffer, NULL)"); GL_EXTCALL(glCompileShaderARB(ret)); checkGLcall("glCompileShaderARB(ret)"); @@ -3283,7 +3289,7 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD */ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv; + struct shader_glsl_priv *priv = This->shader_priv; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; IWineD3DPixelShader *pshader = This->stateBlock->pixelShader; IWineD3DVertexShader *vshader = This->stateBlock->vertexShader; @@ -3293,21 +3299,22 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use int i; char glsl_name[8]; GLhandleARB vshader_id, pshader_id; - struct ps_compile_args compile_args; + struct ps_compile_args ps_compile_args; + struct vs_compile_args vs_compile_args; if(use_vs) { - IWineD3DVertexShaderImpl_CompileShader(vshader); - vshader_id = ((IWineD3DVertexShaderImpl*)vshader)->prgId; + find_vs_compile_args((IWineD3DVertexShaderImpl*)This->stateBlock->vertexShader, This->stateBlock, &vs_compile_args); } else { - vshader_id = 0; + /* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */ + memset(&vs_compile_args, 0, sizeof(vs_compile_args)); } if(use_ps) { - find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelShader, This->stateBlock, &compile_args); + find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelShader, This->stateBlock, &ps_compile_args); } else { /* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */ - memset(&compile_args, 0, sizeof(compile_args)); + memset(&ps_compile_args, 0, sizeof(ps_compile_args)); } - entry = get_glsl_program_entry(priv, vshader_id, pshader, &compile_args); + entry = get_glsl_program_entry(priv, vshader, pshader, &vs_compile_args, &ps_compile_args); if (entry) { priv->glsl_program = entry; return; @@ -3320,9 +3327,10 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use /* Create the entry */ entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link)); entry->programId = programId; - entry->vshader = vshader_id; + entry->vshader = vshader; entry->pshader = pshader; - entry->ps_args = compile_args; + entry->vs_args = vs_compile_args; + entry->ps_args = ps_compile_args; entry->constant_version = 0; /* Add the hash table entry */ add_glsl_program_entry(priv, entry); @@ -3330,6 +3338,12 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use /* Set the current program */ priv->glsl_program = entry; + if(use_vs) { + vshader_id = find_gl_vshader((IWineD3DVertexShaderImpl *) vshader, &vs_compile_args); + } else { + vshader_id = 0; + } + /* Attach GLSL vshader */ if (vshader_id) { int max_attribs = 16; /* TODO: Will this always be the case? It is at the moment... */ @@ -3369,7 +3383,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use } if(use_ps) { - pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &compile_args); + pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args); } else { pshader_id = 0; } @@ -3543,7 +3557,7 @@ static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum t static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv; + struct shader_glsl_priv *priv = This->shader_priv; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; GLhandleARB program_id = 0; GLenum old_vertex_color_clamp, current_vertex_color_clamp; @@ -3573,7 +3587,7 @@ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv; + struct shader_glsl_priv *priv = This->shader_priv; GLhandleARB *blt_program = &priv->depth_blt_program[tex_type]; if (!*blt_program) { @@ -3590,7 +3604,7 @@ static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types t static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv; + struct shader_glsl_priv *priv = This->shader_priv; GLhandleARB program_id; program_id = priv->glsl_program ? priv->glsl_program->programId : 0; @@ -3604,7 +3618,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { const struct list *linked_programs; IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *)device->shader_priv; + struct shader_glsl_priv *priv = device->shader_priv; const WineD3D_GL_Info *gl_info = &device->adapter->gl_info; IWineD3DPixelShaderImpl *ps = NULL; IWineD3DVertexShaderImpl *vs = NULL; @@ -3619,7 +3633,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { if(ps->num_gl_shaders == 0) return; } else { vs = (IWineD3DVertexShaderImpl *) This; - if(vs->prgId == 0) return; + if(vs->num_gl_shaders == 0) return; } linked_programs = &This->baseShader.linked_programs; @@ -3652,22 +3666,29 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { HeapFree(GetProcessHeap(), 0, ps->gl_shaders); ps->gl_shaders = NULL; ps->num_gl_shaders = 0; + ps->shader_array_size = 0; } else { - TRACE("Deleting shader object %u\n", vs->prgId); + UINT i; + ENTER_GL(); - GL_EXTCALL(glDeleteObjectARB(vs->prgId)); - checkGLcall("glDeleteObjectARB"); + for(i = 0; i < vs->num_gl_shaders; i++) { + TRACE("deleting vshader %u\n", vs->gl_shaders[i].prgId); + GL_EXTCALL(glDeleteObjectARB(vs->gl_shaders[i].prgId)); + checkGLcall("glDeleteObjectARB"); + } LEAVE_GL(); - vs->prgId = 0; - vs->baseShader.is_compiled = FALSE; + HeapFree(GetProcessHeap(), 0, vs->gl_shaders); + vs->gl_shaders = NULL; + vs->num_gl_shaders = 0; + vs->shader_array_size = 0; } } static unsigned int glsl_program_key_hash(const void *key) { - const glsl_program_key_t *k = (const glsl_program_key_t *)key; + const glsl_program_key_t *k = key; - unsigned int hash = k->vshader | ((DWORD_PTR) k->pshader) << 16; + unsigned int hash = ((DWORD_PTR) k->vshader) | ((DWORD_PTR) k->pshader) << 16; hash += ~(hash << 15); hash ^= (hash >> 10); hash += (hash << 3); @@ -3680,11 +3701,12 @@ static unsigned int glsl_program_key_hash(const void *key) static BOOL glsl_program_key_compare(const void *keya, const void *keyb) { - const glsl_program_key_t *ka = (const glsl_program_key_t *)keya; - const glsl_program_key_t *kb = (const glsl_program_key_t *)keyb; + const glsl_program_key_t *ka = keya; + const glsl_program_key_t *kb = keyb; return ka->vshader == kb->vshader && ka->pshader == kb->pshader && - (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0); + (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0) && + (memcmp(&ka->vs_args, &kb->vs_args, sizeof(kb->vs_args)) == 0); } static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count) @@ -3752,7 +3774,7 @@ static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) { static void shader_glsl_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; - struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv; + struct shader_glsl_priv *priv = This->shader_priv; int i; for (i = 0; i < tex_type_count; ++i) @@ -3850,10 +3872,16 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor); break; case FOG_EXP: - FIXME("Implement EXP fog in glsl\n"); + /* Fog = e^(-gl_Fog.density * gl_FogFragCoord) */ + shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_FogFragCoord);\n"); + shader_addline(buffer, "Fog = clamp(Fog, 0.0, 1.0);\n"); + shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor); break; case FOG_EXP2: - FIXME("Implement EXP2 fog in glsl\n"); + /* Fog = e^(-(gl_Fog.density * gl_FogFragCoord)^2) */ + shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);\n"); + shader_addline(buffer, "Fog = clamp(Fog, 0.0, 1.0);\n"); + shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor); break; } } @@ -3869,7 +3897,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU return shader_obj; } -static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) { +static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps; CONST DWORD *function = This->baseShader.function; @@ -3890,9 +3918,16 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n"); else shader_addline(buffer, "order_ps_input();\n"); - /* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */ - if (!reg_maps->fog) + /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used + * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE), + * the fog frag coord is thrown away. If the fog frag coord is used, but not written by + * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0) + */ + if(args->fog_src == VS_FOG_Z) { shader_addline(buffer, "gl_FogFragCoord = gl_Position.z;\n"); + } else if (!reg_maps->fog) { + shader_addline(buffer, "gl_FogFragCoord = 0.0;\n"); + } /* Write the final position. * @@ -3919,8 +3954,7 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF GL_EXTCALL(glCompileShaderARB(shader_obj)); print_glsl_info_log(&GLINFO_LOCATION, shader_obj); - /* Store the shader object */ - This->prgId = shader_obj; + return shader_obj; } static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps) diff --git a/reactos/dll/directx/wine/wined3d/pixelshader.c b/reactos/dll/directx/wine/wined3d/pixelshader.c index 9f96c59c0fa..0be352c1adf 100644 --- a/reactos/dll/directx/wine/wined3d/pixelshader.c +++ b/reactos/dll/directx/wine/wined3d/pixelshader.c @@ -34,8 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); #define GLINFO_LOCATION ((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info -#define GLNAME_REQUIRE_GLSL ((const char *)1) - static HRESULT WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) { TRACE("iface %p, riid %s, ppobj %p\n", iface, debugstr_guid(riid), ppobj); @@ -439,8 +437,6 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args); shader_buffer_free(&buffer); - This->baseShader.is_compiled = TRUE; - return retval; } @@ -520,10 +516,12 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args) { UINT i; - struct ps_compiled_shader *old_array; + DWORD new_size; + struct ps_compiled_shader *new_array; /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2), - * so a linear search is more performant than a hashmap + * so a linear search is more performant than a hashmap or a binary search + * (cache coherency etc) */ for(i = 0; i < shader->num_gl_shaders; i++) { if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) { @@ -532,17 +530,22 @@ GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_ } TRACE("No matching GL shader found, compiling a new shader\n"); - old_array = shader->gl_shaders; - if(old_array) { - shader->gl_shaders = HeapReAlloc(GetProcessHeap(), 0, old_array, - (shader->num_gl_shaders + 1) * sizeof(*shader->gl_shaders)); - } else { - shader->gl_shaders = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders)); - } + if(shader->shader_array_size == shader->num_gl_shaders) { + if(shader->gl_shaders) { + new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2); + new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders, + new_size * sizeof(*shader->gl_shaders)); + } else { + new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders)); + new_size = 1; + } - if(!shader->gl_shaders) { - ERR("Out of memory\n"); - return 0; + if(!new_array) { + ERR("Out of memory\n"); + return 0; + } + shader->gl_shaders = new_array; + shader->shader_array_size = new_size; } shader->gl_shaders[shader->num_gl_shaders].args = *args; diff --git a/reactos/dll/directx/wine/wined3d/query.c b/reactos/dll/directx/wine/wined3d/query.c index 05e114c1b5a..481177f4e72 100644 --- a/reactos/dll/directx/wine/wined3d/query.c +++ b/reactos/dll/directx/wine/wined3d/query.c @@ -133,7 +133,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa case WINED3DQUERYTYPE_VCACHE: { - WINED3DDEVINFO_VCACHE *data = (WINED3DDEVINFO_VCACHE *)pData; + WINED3DDEVINFO_VCACHE *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This); if(pData == NULL || dwSize == 0) break; data->Pattern = WINEMAKEFOURCC('C','A','C','H'); @@ -145,7 +145,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_RESOURCEMANAGER: { - WINED3DDEVINFO_RESOURCEMANAGER *data = (WINED3DDEVINFO_RESOURCEMANAGER *)pData; + WINED3DDEVINFO_RESOURCEMANAGER *data = pData; int i; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This); if(pData == NULL || dwSize == 0) break; @@ -169,7 +169,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_VERTEXSTATS: { - WINED3DDEVINFO_VERTEXSTATS *data = (WINED3DDEVINFO_VERTEXSTATS *)pData; + WINED3DDEVINFO_VERTEXSTATS *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This); if(pData == NULL || dwSize == 0) break; data->NumRenderedTriangles = 1; @@ -203,7 +203,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_PIPELINETIMINGS: { - WINED3DDEVINFO_PIPELINETIMINGS *data = (WINED3DDEVINFO_PIPELINETIMINGS *)pData; + WINED3DDEVINFO_PIPELINETIMINGS *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This); if(pData == NULL || dwSize == 0) break; @@ -215,7 +215,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_INTERFACETIMINGS: { - WINED3DDEVINFO_INTERFACETIMINGS *data = (WINED3DDEVINFO_INTERFACETIMINGS *)pData; + WINED3DDEVINFO_INTERFACETIMINGS *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This); if(pData == NULL || dwSize == 0) break; @@ -229,7 +229,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_VERTEXTIMINGS: { - WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData; + WINED3DDEVINFO_STAGETIMINGS *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This); if(pData == NULL || dwSize == 0) break; @@ -240,7 +240,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_PIXELTIMINGS: { - WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData; + WINED3DDEVINFO_STAGETIMINGS *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This); if(pData == NULL || dwSize == 0) break; @@ -250,7 +250,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_BANDWIDTHTIMINGS: { - WINED3DDEVINFO_BANDWIDTHTIMINGS *data = (WINED3DDEVINFO_BANDWIDTHTIMINGS *)pData; + WINED3DDEVINFO_BANDWIDTHTIMINGS *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This); if(pData == NULL || dwSize == 0) break; @@ -263,7 +263,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa break; case WINED3DQUERYTYPE_CACHEUTILIZATION: { - WINED3DDEVINFO_CACHEUTILIZATION *data = (WINED3DDEVINFO_CACHEUTILIZATION *)pData; + WINED3DDEVINFO_CACHEUTILIZATION *data = pData; FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This); if(pData == NULL || dwSize == 0) break; diff --git a/reactos/dll/directx/wine/wined3d/resource.c b/reactos/dll/directx/wine/wined3d/resource.c index 1231b34a988..b4e49b1a322 100644 --- a/reactos/dll/directx/wine/wined3d/resource.c +++ b/reactos/dll/directx/wine/wined3d/resource.c @@ -25,7 +25,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent) diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 67fc1c7648f..e1aeeab6985 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -1019,75 +1019,72 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D * and 2) disables the fog computation (in either the fixed function or programmable * rasterizer) if using a vertex program. * + * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with + * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear + * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in + * the specular color, a vertex shader counts as pretransformed geometry in this case. + * There are some GL differences between specular fog coords and vertex shaders though. + * + * With table fog the vertex shader fog coordinate is ignored. * * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or * without shaders). */ - if (use_vs(stateblock) && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) { - if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) { - FIXME("vertex shader with table fog used\n"); - } else { - /* Set fog computation in the rasterizer to pass through the value (just blend it) */ - glFogi(GL_FOG_MODE, GL_LINEAR); - checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); - } - context->last_was_foggy_shader = TRUE; - new_source = FOGSOURCE_VS; - } /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes, * the system will apply only pixel(=table) fog effects." */ - else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { - context->last_was_foggy_shader = FALSE; - - switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) { - /* If processed vertices are used, fall through to the NONE case */ - case WINED3DFOG_EXP: - if(!context->last_was_rhw) { - glFogi(GL_FOG_MODE, GL_EXP); - checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)"); - new_source = FOGSOURCE_FFP; - break; - } - /* drop through */ - - case WINED3DFOG_EXP2: - if(!context->last_was_rhw) { - glFogi(GL_FOG_MODE, GL_EXP2); - checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)"); - new_source = FOGSOURCE_FFP; - break; - } - /* drop through */ + if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { + if(use_vs(stateblock)) { + glFogi(GL_FOG_MODE, GL_LINEAR); + checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); + new_source = FOGSOURCE_VS; + } else { + switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) { + /* If processed vertices are used, fall through to the NONE case */ + case WINED3DFOG_EXP: + if(!context->last_was_rhw) { + glFogi(GL_FOG_MODE, GL_EXP); + checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)"); + new_source = FOGSOURCE_FFP; + break; + } + /* drop through */ + + case WINED3DFOG_EXP2: + if(!context->last_was_rhw) { + glFogi(GL_FOG_MODE, GL_EXP2); + checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)"); + new_source = FOGSOURCE_FFP; + break; + } + /* drop through */ + + case WINED3DFOG_LINEAR: + if(!context->last_was_rhw) { + glFogi(GL_FOG_MODE, GL_LINEAR); + checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); + new_source = FOGSOURCE_FFP; + break; + } + /* drop through */ - case WINED3DFOG_LINEAR: - if(!context->last_was_rhw) { + case WINED3DFOG_NONE: + /* Both are none? According to msdn the alpha channel of the specular + * color contains a fog factor. Set it in drawStridedSlow. + * Same happens with Vertexfog on transformed vertices + */ + new_source = FOGSOURCE_COORD; glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); - new_source = FOGSOURCE_FFP; break; - } - /* drop through */ - case WINED3DFOG_NONE: - /* Both are none? According to msdn the alpha channel of the specular - * color contains a fog factor. Set it in drawStridedSlow. - * Same happens with Vertexfog on transformed vertices - */ - new_source = FOGSOURCE_COORD; - glFogi(GL_FOG_MODE, GL_LINEAR); - checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); - break; - - default: - FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]); - new_source = FOGSOURCE_FFP; /* Make the compiler happy */ + default: + FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]); + new_source = FOGSOURCE_FFP; /* Make the compiler happy */ + } } } else { - glHint(GL_FOG_HINT, GL_NICEST); - checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)"); - context->last_was_foggy_shader = FALSE; new_source = FOGSOURCE_FFP; switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) { @@ -3928,8 +3925,18 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, case WINED3DDECLTYPE_UBYTE4: GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr)); break; - case WINED3DDECLTYPE_UBYTE4N: case WINED3DDECLTYPE_D3DCOLOR: + if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA)) + { + const DWORD *src = (const DWORD *)ptr; + DWORD c = *src & 0xff00ff00; + c |= (*src & 0xff0000) >> 16; + c |= (*src & 0xff) << 16; + GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c)); + break; + } + /* else fallthrough */ + case WINED3DDECLTYPE_UBYTE4N: GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr)); break; @@ -4270,10 +4277,12 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo load_numbered = TRUE; device->useDrawStridedSlow = FALSE; } - } else if (fixup || GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) || - (dataLocations->u.s.pSize.lpData == NULL && - dataLocations->u.s.diffuse.lpData == NULL && - dataLocations->u.s.specular.lpData == NULL)) { + } else if (fixup || (!dataLocations->u.s.pSize.lpData + && !dataLocations->position_transformed + && (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) + || (!dataLocations->u.s.diffuse.lpData + && !dataLocations->u.s.specular.lpData)))) + { /* Load the vertex data using named arrays */ load_named = TRUE; device->useDrawStridedSlow = FALSE; @@ -4331,15 +4340,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; BOOL wasrhw = context->last_was_rhw; - if (useVertexShaderFunction) - { - if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) { - updateFog = TRUE; - } - } else if(context->last_was_foggy_shader) { - updateFog = TRUE; - } - transformed = device->strided_streams.position_transformed; if(transformed != context->last_was_rhw && !useVertexShaderFunction) { updateFog = TRUE; @@ -4405,8 +4405,11 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context); } - if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) { - state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context); + if(context->last_was_vshader) { + updateFog = TRUE; + if(!isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) { + state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context); + } } if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) { state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context); @@ -4440,6 +4443,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context); } } + updateFog = TRUE; } } diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index 03d483a2ad0..c3d56ee40e5 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -2228,7 +2228,7 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve glEnable(GL_FRAGMENT_PROGRAM_ARB); GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader)); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader)); - GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragment_palette_conversion), (const GLbyte *)fragment_palette_conversion)); + GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragment_palette_conversion), fragment_palette_conversion)); glDisable(GL_FRAGMENT_PROGRAM_ARB); } diff --git a/reactos/dll/directx/wine/wined3d/surface_base.c b/reactos/dll/directx/wine/wined3d/surface_base.c index f023c2e4828..12917019cb8 100644 --- a/reactos/dll/directx/wine/wined3d/surface_base.c +++ b/reactos/dll/directx/wine/wined3d/surface_base.c @@ -29,7 +29,6 @@ #include "config.h" #include "wine/port.h" #include "wined3d_private.h" -#include "float.h" #include @@ -46,7 +45,7 @@ static inline unsigned short float_32_to_16(const float *in) /* Deal with special numbers */ if(*in == 0.0) return 0x0000; if(isnan(*in)) return 0x7C01; - if(!_finite(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00); + if(isinf(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00); if(tmp < pow(2, 10)) { do @@ -1145,7 +1144,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D assert(width <= dlock.Pitch); if (DestRect && Src != This) - dbuf = (BYTE*)dlock.pBits; + dbuf = dlock.pBits; else dbuf = (BYTE*)dlock.pBits+(xdst.top*dlock.Pitch)+(xdst.left*bpp); diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index cc09584b726..808b8c7d2cf 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -1365,8 +1365,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B } #undef GLINFO_LOCATION -#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info - /* This small helper function is used to convert a bitmask into the number of masked bits */ unsigned int count_bits(unsigned int mask) { @@ -1457,8 +1455,6 @@ BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize return TRUE; } -#undef GLINFO_LOCATION - /* DirectDraw stuff */ WINED3DFORMAT pixelformat_for_depth(DWORD depth) { switch(depth) { @@ -2096,17 +2092,21 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) { settings->fog = FOG_OFF; } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { - switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) { - case WINED3DFOG_NONE: - case WINED3DFOG_LINEAR: - settings->fog = FOG_LINEAR; - break; - case WINED3DFOG_EXP: - settings->fog = FOG_EXP; - break; - case WINED3DFOG_EXP2: - settings->fog = FOG_EXP2; - break; + if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) { + settings->fog = FOG_LINEAR; + } else { + switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) { + case WINED3DFOG_NONE: + case WINED3DFOG_LINEAR: + settings->fog = FOG_LINEAR; + break; + case WINED3DFOG_EXP: + settings->fog = FOG_EXP; + break; + case WINED3DFOG_EXP2: + settings->fog = FOG_EXP2; + break; + } } } else { switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) { @@ -2132,7 +2132,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders, const struct ffp_frag_settings *settings) { - return (const struct ffp_frag_desc *)hash_table_get(fragment_shaders, settings); + return hash_table_get(fragment_shaders, settings); } void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) { @@ -2241,7 +2241,7 @@ void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont unsigned int ffp_frag_program_key_hash(const void *key) { - const struct ffp_frag_settings *k = (const struct ffp_frag_settings *)key; + const struct ffp_frag_settings *k = key; unsigned int hash = 0, i; const DWORD *blob; @@ -2268,8 +2268,8 @@ unsigned int ffp_frag_program_key_hash(const void *key) BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb) { - const struct ffp_frag_settings *ka = (const struct ffp_frag_settings *)keya; - const struct ffp_frag_settings *kb = (const struct ffp_frag_settings *)keyb; + const struct ffp_frag_settings *ka = keya; + const struct ffp_frag_settings *kb = keyb; return memcmp(ka, kb, sizeof(*ka)) == 0; } diff --git a/reactos/dll/directx/wine/wined3d/vertexshader.c b/reactos/dll/directx/wine/wined3d/vertexshader.c index 339d955e230..e8d4b84d85d 100644 --- a/reactos/dll/directx/wine/wined3d/vertexshader.c +++ b/reactos/dll/directx/wine/wined3d/vertexshader.c @@ -37,8 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); /* TODO: Vertex and Pixel shaders are almost identical, the only exception being the way that some of the data is looked up or the availability of some of the data i.e. some instructions are only valid for pshaders and some for vshaders because of this the bulk of the software pipeline can be shared between pixel and vertex shaders... and it wouldn't surprise me if the program can be cross compiled using a large body of shared code */ -#define GLNAME_REQUIRE_GLSL ((const char *)1) - CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = { /* This table is not order or position dependent. */ @@ -218,21 +216,6 @@ BOOL vshader_get_input( return FALSE; } -/** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB - or GLSL and send it to the card */ -static void IWineD3DVertexShaderImpl_GenerateShader(IWineD3DVertexShader *iface, - const struct shader_reg_maps* reg_maps, const DWORD *pFunction) -{ - IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; - SHADER_BUFFER buffer; - - This->swizzle_map = ((IWineD3DDeviceImpl *)This->baseShader.device)->strided_streams.swizzle_map; - - shader_buffer_init(&buffer); - ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_generate_vshader(iface, &buffer); - shader_buffer_free(&buffer); -} - /* ******************************************* IWineD3DVertexShader IUnknown parts follow ******************************************* */ @@ -418,40 +401,20 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex return WINED3D_OK; } -HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) { - IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; - CONST DWORD *function = This->baseShader.function; +static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct vs_compile_args *args) { IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device; - - TRACE("(%p) : function %p\n", iface, function); - - /* We're already compiled. */ - if (This->baseShader.is_compiled) { - if ((This->swizzle_map & deviceImpl->strided_streams.use_map) != deviceImpl->strided_streams.swizzle_map) - { - WARN("Recompiling vertex shader %p due to D3DCOLOR input changes\n", This); - goto recompile; - } - - return WINED3D_OK; - - recompile: - if(This->recompile_count < 50) { - This->recompile_count++; - } else { - FIXME("Vertexshader %p recompiled more than 50 times\n", This); - } - - deviceImpl->shader_backend->shader_destroy((IWineD3DBaseShader *) iface); - } + SHADER_BUFFER buffer; + GLuint ret; /* Generate the HW shader */ TRACE("(%p) : Generating hardware program\n", This); - IWineD3DVertexShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function); - - This->baseShader.is_compiled = TRUE; + shader_buffer_init(&buffer); + This->cur_args = args; + ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This, &buffer, args); + This->cur_args = NULL; + shader_buffer_free(&buffer); - return WINED3D_OK; + return ret; } const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl = @@ -470,3 +433,56 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl = IWineD3DVertexShaderImpl_FakeSemantics, IWIneD3DVertexShaderImpl_SetLocalConstantsF }; + +void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args) { + args->fog_src = stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ? VS_FOG_COORD : VS_FOG_Z; + args->swizzle_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.swizzle_map; +} + +static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new, + const DWORD use_map) { + if((stored->swizzle_map & use_map) != new->swizzle_map) return FALSE; + return stored->fog_src == new->fog_src; +} + +GLuint find_gl_vshader(IWineD3DVertexShaderImpl *shader, const struct vs_compile_args *args) +{ + UINT i; + DWORD new_size = shader->shader_array_size; + struct vs_compiled_shader *new_array; + DWORD use_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.use_map; + + /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2), + * so a linear search is more performant than a hashmap or a binary search + * (cache coherency etc) + */ + for(i = 0; i < shader->num_gl_shaders; i++) { + if(vs_args_equal(&shader->gl_shaders[i].args, args, use_map)) { + return shader->gl_shaders[i].prgId; + } + } + + TRACE("No matching GL shader found, compiling a new shader\n"); + + if(shader->shader_array_size == shader->num_gl_shaders) { + if(shader->gl_shaders) { + new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2); + new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders, + new_size * sizeof(*shader->gl_shaders)); + } else { + new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders)); + new_size = 1; + } + + if(!new_array) { + ERR("Out of memory\n"); + return 0; + } + shader->gl_shaders = new_array; + shader->shader_array_size = new_size; + } + + shader->gl_shaders[shader->num_gl_shaders].args = *args; + shader->gl_shaders[shader->num_gl_shaders].prgId = vertexshader_compile(shader, args); + return shader->gl_shaders[shader->num_gl_shaders++].prgId; +} diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index 07ca0d51826..dd3946ea9b7 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -3257,6 +3257,7 @@ typedef enum _GL_Cards { CARD_ATI_RADEON_7200 = 0x5144, CARD_ATI_RADEON_8500 = 0x514c, CARD_ATI_RADEON_9500 = 0x4144, + CARD_ATI_RADEON_XPRESS_200M = 0x5955, CARD_ATI_RADEON_X700 = 0x5e4c, CARD_ATI_RADEON_X1600 = 0x71c2, CARD_ATI_RADEON_HD2300 = 0x7210, diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 0965a77fcd2..99015ac530d 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -461,6 +461,18 @@ struct ps_compile_args { /* Texture types(2D, Cube, 3D) in ps 1.x */ }; +#define MAX_ATTRIBS 16 + +enum fog_src_type { + VS_FOG_Z = 0, + VS_FOG_COORD = 1 +}; + +struct vs_compile_args { + WORD fog_src; + WORD swizzle_map; /* MAX_ATTRIBS, 16 */ +}; + typedef struct { const SHADER_HANDLER *shader_instruction_handler_table; void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS); @@ -475,7 +487,7 @@ typedef struct { void (*shader_free_private)(IWineD3DDevice *iface); BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface); GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args); - void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer); + GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args); void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps); BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup); } shader_backend_t; @@ -804,7 +816,6 @@ struct WineD3DContext { WORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */ WORD last_was_pshader : 1; WORD last_was_vshader : 1; - WORD last_was_foggy_shader : 1; WORD namedArraysLoaded : 1; WORD numberedArraysLoaded : 1; WORD last_was_blit : 1; @@ -813,7 +824,7 @@ struct WineD3DContext { WORD isPBuffer : 1; WORD fog_enabled : 1; WORD num_untracked_materials : 2; /* Max value 2 */ - WORD padding : 2; + WORD padding : 3; BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */ BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */ DWORD numbered_array_mask; @@ -2210,7 +2221,6 @@ typedef struct IWineD3DBaseShaderClass CONST SHADER_OPCODE *shader_ins; DWORD *function; UINT functionLength; - BOOL is_compiled; UINT cur_loop_depth, cur_loop_regno; BOOL load_local_constsF; BOOL uses_bool_consts, uses_int_consts; @@ -2326,8 +2336,14 @@ static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD } /***************************************************************************** - * IDirect3DVertexShader implementation structure + * IDirect3DVertexShader implementation structures */ + +struct vs_compiled_shader { + struct vs_compile_args args; + GLuint prgId; +}; + typedef struct IWineD3DVertexShaderImpl { /* IUnknown parts*/ const IWineD3DVertexShaderVtbl *lpVtbl; @@ -2341,22 +2357,25 @@ typedef struct IWineD3DVertexShaderImpl { DWORD usage; /* The GL shader */ - GLuint prgId; + struct vs_compiled_shader *gl_shaders; + UINT num_gl_shaders, shader_array_size; /* Vertex shader input and output semantics */ semantic semantics_in [MAX_ATTRIBS]; semantic semantics_out [MAX_REG_OUTPUT]; - WORD swizzle_map; /* MAX_ATTRIBS, 16 */ - UINT min_rel_offset, max_rel_offset; UINT rel_offset; UINT recompile_count; + + const struct vs_compile_args *cur_args; } IWineD3DVertexShaderImpl; extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[]; extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl; -HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface); + +void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args); +GLuint find_gl_vshader(IWineD3DVertexShaderImpl *shader, const struct vs_compile_args *args); /***************************************************************************** * IDirect3DPixelShader implementation structure @@ -2384,7 +2403,7 @@ typedef struct IWineD3DPixelShaderImpl { /* The GL shader */ struct ps_compiled_shader *gl_shaders; - UINT num_gl_shaders; + UINT num_gl_shaders, shader_array_size; /* Some information about the shader behavior */ struct stb_const_desc bumpenvmatconst[MAX_TEXTURES];