mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 18:02:55 +00:00
- update wined3d/d3d8/d3d9 to Wine 1.1.15
svn path=/trunk/; revision=39607
This commit is contained in:
parent
805ca6f02a
commit
43961e394e
|
@ -2265,19 +2265,19 @@ static inline struct IDirect3DDevice8Impl *device_from_device_parent(IWineD3DDev
|
||||||
- FIELD_OFFSET(struct IDirect3DDevice8Impl, device_parent_vtbl));
|
- 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);
|
struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
|
||||||
return IDirect3DDevice8Impl_QueryInterface((IDirect3DDevice8 *)This, riid, object);
|
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);
|
struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
|
||||||
return IDirect3DDevice8Impl_AddRef((IDirect3DDevice8 *)This);
|
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);
|
struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
|
||||||
return IDirect3DDevice8Impl_Release((IDirect3DDevice8 *)This);
|
return IDirect3DDevice8Impl_Release((IDirect3DDevice8 *)This);
|
||||||
|
|
|
@ -265,7 +265,7 @@ static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX ifac
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
|
static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
|
||||||
BOOL *resources_ok = (BOOL *) data;
|
BOOL *resources_ok = data;
|
||||||
WINED3DRESOURCETYPE type;
|
WINED3DRESOURCETYPE type;
|
||||||
HRESULT ret = S_OK;
|
HRESULT ret = S_OK;
|
||||||
WINED3DSURFACE_DESC surface_desc;
|
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);
|
TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter);
|
||||||
EnterCriticalSection(&d3d9_cs);
|
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);
|
LeaveCriticalSection(&d3d9_cs);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -1338,7 +1338,7 @@ static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This,
|
||||||
|
|
||||||
static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
|
static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
|
||||||
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
|
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
|
||||||
HRESULT hr;
|
HRESULT hr = S_OK;
|
||||||
TRACE("(%p) Relay\n" , This);
|
TRACE("(%p) Relay\n" , This);
|
||||||
|
|
||||||
EnterCriticalSection(&d3d9_cs);
|
EnterCriticalSection(&d3d9_cs);
|
||||||
|
|
|
@ -37,7 +37,7 @@ static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9EX iface, REFIID
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} else if(IsEqualGUID(riid, &IID_IDirect3D9Ex)) {
|
} else if(IsEqualGUID(riid, &IID_IDirect3D9Ex)) {
|
||||||
if(This->extended) {
|
if(This->extended) {
|
||||||
*ppobj = (IDirect3D9Ex *) This;
|
*ppobj = This;
|
||||||
TRACE("Returning IDirect3D9Ex interface at %p\n", *ppobj);
|
TRACE("Returning IDirect3D9Ex interface at %p\n", *ppobj);
|
||||||
IDirect3D9Ex_AddRef((IDirect3D9Ex *)*ppobj);
|
IDirect3D9Ex_AddRef((IDirect3D9Ex *)*ppobj);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -510,7 +510,7 @@ static void vshader_program_add_param(const SHADER_OPCODE_ARG *arg, const DWORD
|
||||||
break;
|
break;
|
||||||
case WINED3DSPR_INPUT:
|
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);
|
sprintf(tmpReg, "vertex.attrib[%u]", reg);
|
||||||
strcat(hwLine, tmpReg);
|
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) {
|
static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)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;
|
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
||||||
|
|
||||||
if (useVS) {
|
if (useVS) {
|
||||||
TRACE("Using vertex shader\n");
|
struct vs_compile_args compile_args;
|
||||||
IWineD3DVertexShaderImpl_CompileShader(This->stateBlock->vertexShader);
|
|
||||||
|
|
||||||
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 */
|
/* Bind the vertex program */
|
||||||
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
|
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 */
|
/* Enable OpenGL vertex programs */
|
||||||
glEnable(GL_VERTEX_PROGRAM_ARB);
|
glEnable(GL_VERTEX_PROGRAM_ARB);
|
||||||
|
@ -1773,7 +1774,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
|
||||||
|
|
||||||
/* Bind the fragment program */
|
/* Bind the fragment program */
|
||||||
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
|
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) {
|
if(!priv->use_arbfp_fixed_func) {
|
||||||
/* Enable OpenGL fragment programs */
|
/* 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) {
|
static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)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;
|
||||||
GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type];
|
GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type];
|
||||||
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
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) {
|
static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)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;
|
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
||||||
|
|
||||||
if (priv->current_vprogram_id) {
|
if (priv->current_vprogram_id) {
|
||||||
|
@ -1857,16 +1858,22 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
|
||||||
HeapFree(GetProcessHeap(), 0, This->gl_shaders);
|
HeapFree(GetProcessHeap(), 0, This->gl_shaders);
|
||||||
This->gl_shaders = NULL;
|
This->gl_shaders = NULL;
|
||||||
This->num_gl_shaders = 0;
|
This->num_gl_shaders = 0;
|
||||||
|
This->shader_array_size = 0;
|
||||||
} else {
|
} else {
|
||||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
|
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
|
||||||
|
UINT i;
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId));
|
for(i = 0; i < This->num_gl_shaders; i++) {
|
||||||
checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId))");
|
GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId));
|
||||||
((IWineD3DVertexShaderImpl *) This)->prgId = 0;
|
checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))");
|
||||||
|
}
|
||||||
LEAVE_GL();
|
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) {
|
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) {
|
static void shader_arb_free(IWineD3DDevice *iface) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
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;
|
int i;
|
||||||
|
|
||||||
if(priv->depth_blt_vprogram_id) {
|
if(priv->depth_blt_vprogram_id) {
|
||||||
|
@ -2007,13 +2014,14 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
|
||||||
return retval;
|
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;
|
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||||
const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
|
const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
|
||||||
CONST DWORD *function = This->baseShader.function;
|
CONST DWORD *function = This->baseShader.function;
|
||||||
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
|
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
|
||||||
const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
|
const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
|
||||||
const local_constant *lconst;
|
const local_constant *lconst;
|
||||||
|
GLuint ret;
|
||||||
|
|
||||||
/* Create the hw ARB shader */
|
/* Create the hw ARB shader */
|
||||||
shader_addline(buffer, "!!ARBvp1.0\n");
|
shader_addline(buffer, "!!ARBvp1.0\n");
|
||||||
|
@ -2060,9 +2068,16 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
|
||||||
/* Base Shader Body */
|
/* Base Shader Body */
|
||||||
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
|
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 */
|
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
|
||||||
if (!reg_maps->fog)
|
* 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");
|
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.
|
/* Write the final position.
|
||||||
*
|
*
|
||||||
|
@ -2085,12 +2100,12 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
|
||||||
shader_addline(buffer, "END\n");
|
shader_addline(buffer, "END\n");
|
||||||
|
|
||||||
/* TODO: change to resource.glObjectHandle or something like that */
|
/* 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);
|
TRACE("Creating a hw vertex shader, prg=%d\n", ret);
|
||||||
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->prgId));
|
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 */
|
/* Create the program and check for errors */
|
||||||
GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
|
GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
|
||||||
buffer->bsize, buffer->buffer));
|
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);
|
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
|
||||||
FIXME("HW VertexShader Error at position %d: %s\n",
|
FIXME("HW VertexShader Error at position %d: %s\n",
|
||||||
errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
|
errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
|
||||||
This->prgId = -1;
|
ret = -1;
|
||||||
}
|
} else {
|
||||||
|
/* Load immediate constants */
|
||||||
/* Load immediate constants */
|
if(!This->baseShader.load_local_constsF) {
|
||||||
if(!This->baseShader.load_local_constsF) {
|
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
|
||||||
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
|
const float *value = (const float *)lconst->value;
|
||||||
const float *value = (const float *)lconst->value;
|
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, 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)
|
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));
|
This->fragment_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_arb_priv));
|
||||||
if(!This->fragment_priv) return E_OUTOFMEMORY;
|
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->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
|
||||||
priv->use_arbfp_fixed_func = TRUE;
|
priv->use_arbfp_fixed_func = TRUE;
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
|
@ -2313,7 +2329,7 @@ static void arbfp_free_ffpshader(void *value, void *gli) {
|
||||||
|
|
||||||
static void arbfp_free(IWineD3DDevice *iface) {
|
static void arbfp_free(IWineD3DDevice *iface) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) 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);
|
hash_table_destroy(priv->fragment_shaders, arbfp_free_ffpshader, &This->adapter->gl_info);
|
||||||
priv->use_arbfp_fixed_func = FALSE;
|
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) {
|
static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
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_pshader = use_ps(stateblock);
|
||||||
BOOL use_vshader = use_vs(stateblock);
|
BOOL use_vshader = use_vs(stateblock);
|
||||||
struct ffp_frag_settings settings;
|
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(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
|
||||||
|
|
||||||
if(use_vs(stateblock)
|
if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||||
&& ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
|
if(use_vs(stateblock)) {
|
||||||
if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
|
new_source = FOGSOURCE_VS;
|
||||||
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;
|
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
context->last_was_foggy_shader = FALSE;
|
|
||||||
new_source = FOGSOURCE_FFP;
|
new_source = FOGSOURCE_FFP;
|
||||||
}
|
}
|
||||||
if(new_source != context->fog_source) {
|
if(new_source != context->fog_source) {
|
||||||
|
@ -3263,7 +3274,7 @@ static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) {
|
||||||
}
|
}
|
||||||
static void arbfp_blit_free(IWineD3DDevice *iface) {
|
static void arbfp_blit_free(IWineD3DDevice *iface) {
|
||||||
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) 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();
|
ENTER_GL();
|
||||||
GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_rect_shader));
|
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;
|
GLenum shader;
|
||||||
SHADER_BUFFER buffer;
|
SHADER_BUFFER buffer;
|
||||||
char luminance_component;
|
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 header */
|
||||||
shader_buffer_init(&buffer);
|
shader_buffer_init(&buffer);
|
||||||
|
@ -3649,7 +3660,7 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum t
|
||||||
GLenum shader;
|
GLenum shader;
|
||||||
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
|
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
|
||||||
float size[4] = {width, height, 1, 1};
|
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;
|
const struct GlPixelFormatDesc *glDesc;
|
||||||
enum yuv_fixup yuv_fixup;
|
enum yuv_fixup yuv_fixup;
|
||||||
|
|
||||||
|
|
|
@ -803,7 +803,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
|
||||||
IWineD3DDeviceImpl *This = stateblock->wineD3DDevice;
|
IWineD3DDeviceImpl *This = stateblock->wineD3DDevice;
|
||||||
const struct atifs_ffp_desc *desc;
|
const struct atifs_ffp_desc *desc;
|
||||||
struct ffp_frag_settings settings;
|
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;
|
DWORD mapped_stage;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -1107,7 +1107,7 @@ static HRESULT atifs_alloc(IWineD3DDevice *iface) {
|
||||||
ERR("Out of memory\n");
|
ERR("Out of memory\n");
|
||||||
return E_OUTOFMEMORY;
|
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);
|
priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1126,7 @@ static void atifs_free_ffpshader(void *value, void *device) {
|
||||||
|
|
||||||
static void atifs_free(IWineD3DDevice *iface) {
|
static void atifs_free(IWineD3DDevice *iface) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) 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);
|
hash_table_destroy(priv->fragment_shaders, atifs_free_ffpshader, This);
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(d3d);
|
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 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) {
|
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");
|
FIXME("NONE shader backend asked to generate a pixel shader\n");
|
||||||
return 0;
|
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");
|
FIXME("NONE shader backend asked to generate a vertex shader\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GLINFO_LOCATION (*gl_info)
|
#define GLINFO_LOCATION (*gl_info)
|
||||||
|
|
|
@ -2104,7 +2104,7 @@ static void IWineD3DDeviceImpl_LoadLogo(IWineD3DDeviceImpl *This, const char *fi
|
||||||
HDC dcb = NULL, dcs = NULL;
|
HDC dcb = NULL, dcs = NULL;
|
||||||
WINEDDCOLORKEY colorkey;
|
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)
|
if(hbm)
|
||||||
{
|
{
|
||||||
GetObjectA(hbm, sizeof(BITMAP), &bm);
|
GetObjectA(hbm, sizeof(BITMAP), &bm);
|
||||||
|
@ -6765,7 +6765,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
|
||||||
{
|
{
|
||||||
const struct GlPixelFormatDesc *glDesc;
|
const struct GlPixelFormatDesc *glDesc;
|
||||||
const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(WINED3DFMT_A8R8G8B8, &GLINFO_LOCATION, &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 intfmt = glDesc->glInternal;
|
||||||
GLint format = glDesc->glFormat;
|
GLint format = glDesc->glFormat;
|
||||||
GLint type = glDesc->glType;
|
GLint type = glDesc->glType;
|
||||||
|
|
|
@ -1287,6 +1287,12 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
|
||||||
gl_info->gl_card = CARD_ATI_RADEON_X700;
|
gl_info->gl_card = CARD_ATI_RADEON_X700;
|
||||||
vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
|
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 */
|
/* Radeon R3xx */
|
||||||
else {
|
else {
|
||||||
gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
|
gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
|
||||||
|
|
|
@ -324,8 +324,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
|
||||||
idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory;
|
idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idxSize == 2) pIdxBufS = (const WORD *) idxData;
|
if (idxSize == 2) pIdxBufS = idxData;
|
||||||
else pIdxBufL = (const DWORD *) idxData;
|
else pIdxBufL = idxData;
|
||||||
} else if (idxData) {
|
} else if (idxData) {
|
||||||
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
|
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
|
||||||
return;
|
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) {
|
static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, const UINT index, const void *ptr) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case WINED3DDECLTYPE_FLOAT1:
|
case WINED3DDECLTYPE_FLOAT1:
|
||||||
GL_EXTCALL(glVertexAttrib1fvARB(index, (const float *)ptr));
|
GL_EXTCALL(glVertexAttrib1fvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
case WINED3DDECLTYPE_FLOAT2:
|
case WINED3DDECLTYPE_FLOAT2:
|
||||||
GL_EXTCALL(glVertexAttrib2fvARB(index, (const float *)ptr));
|
GL_EXTCALL(glVertexAttrib2fvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
case WINED3DDECLTYPE_FLOAT3:
|
case WINED3DDECLTYPE_FLOAT3:
|
||||||
GL_EXTCALL(glVertexAttrib3fvARB(index, (const float *)ptr));
|
GL_EXTCALL(glVertexAttrib3fvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
case WINED3DDECLTYPE_FLOAT4:
|
case WINED3DDECLTYPE_FLOAT4:
|
||||||
GL_EXTCALL(glVertexAttrib4fvARB(index, (const float *)ptr));
|
GL_EXTCALL(glVertexAttrib4fvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WINED3DDECLTYPE_UBYTE4:
|
case WINED3DDECLTYPE_UBYTE4:
|
||||||
GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
|
GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
case WINED3DDECLTYPE_UBYTE4N:
|
|
||||||
case WINED3DDECLTYPE_D3DCOLOR:
|
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));
|
GL_EXTCALL(glVertexAttrib4NubvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WINED3DDECLTYPE_SHORT2:
|
case WINED3DDECLTYPE_SHORT2:
|
||||||
GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr));
|
GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
case WINED3DDECLTYPE_SHORT4:
|
case WINED3DDECLTYPE_SHORT4:
|
||||||
GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr));
|
GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WINED3DDECLTYPE_SHORT2N:
|
case WINED3DDECLTYPE_SHORT2N:
|
||||||
|
@ -559,10 +569,10 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WINED3DDECLTYPE_SHORT4N:
|
case WINED3DDECLTYPE_SHORT4N:
|
||||||
GL_EXTCALL(glVertexAttrib4NsvARB(index, (const GLshort *)ptr));
|
GL_EXTCALL(glVertexAttrib4NsvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
case WINED3DDECLTYPE_USHORT4N:
|
case WINED3DDECLTYPE_USHORT4N:
|
||||||
GL_EXTCALL(glVertexAttrib4NusvARB(index, (const GLushort *)ptr));
|
GL_EXTCALL(glVertexAttrib4NusvARB(index, ptr));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WINED3DDECLTYPE_UDEC3:
|
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
|
* byte float according to the IEEE standard
|
||||||
*/
|
*/
|
||||||
if (GL_SUPPORT(NV_HALF_FLOAT)) {
|
if (GL_SUPPORT(NV_HALF_FLOAT)) {
|
||||||
GL_EXTCALL(glVertexAttrib2hvNV(index, (const GLhalfNV *)ptr));
|
GL_EXTCALL(glVertexAttrib2hvNV(index, ptr));
|
||||||
} else {
|
} else {
|
||||||
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
||||||
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
|
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;
|
break;
|
||||||
case WINED3DDECLTYPE_FLOAT16_4:
|
case WINED3DDECLTYPE_FLOAT16_4:
|
||||||
if (GL_SUPPORT(NV_HALF_FLOAT)) {
|
if (GL_SUPPORT(NV_HALF_FLOAT)) {
|
||||||
GL_EXTCALL(glVertexAttrib4hvNV(index, (const GLhalfNV *)ptr));
|
GL_EXTCALL(glVertexAttrib4hvNV(index, ptr));
|
||||||
} else {
|
} else {
|
||||||
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
||||||
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
|
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;
|
idxData = ((IWineD3DIndexBufferImpl *) stateblock->pIndexData)->resource.allocatedMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idxSize == 2) pIdxBufS = (const WORD *) idxData;
|
if (idxSize == 2) pIdxBufS = idxData;
|
||||||
else pIdxBufL = (const DWORD *) idxData;
|
else pIdxBufL = idxData;
|
||||||
} else if (idxData) {
|
} else if (idxData) {
|
||||||
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
|
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
|
||||||
return;
|
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);
|
sprintf(buffer, "/tmp/texture_%p_%ld_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo);
|
||||||
TRACE("Saving texture %s\n", buffer);
|
TRACE("Saving texture %s\n", buffer);
|
||||||
if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) {
|
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_SaveSnapshot(pSur, buffer);
|
||||||
IWineD3DSurface_Release(pSur);
|
IWineD3DSurface_Release(pSur);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -101,16 +101,18 @@ struct glsl_shader_prog_link {
|
||||||
GLhandleARB luminanceoffset_location[MAX_TEXTURES];
|
GLhandleARB luminanceoffset_location[MAX_TEXTURES];
|
||||||
GLhandleARB ycorrection_location;
|
GLhandleARB ycorrection_location;
|
||||||
GLenum vertex_color_clamp;
|
GLenum vertex_color_clamp;
|
||||||
GLhandleARB vshader;
|
IWineD3DVertexShader *vshader;
|
||||||
IWineD3DPixelShader *pshader;
|
IWineD3DPixelShader *pshader;
|
||||||
|
struct vs_compile_args vs_args;
|
||||||
struct ps_compile_args ps_args;
|
struct ps_compile_args ps_args;
|
||||||
UINT constant_version;
|
UINT constant_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLhandleARB vshader;
|
IWineD3DVertexShader *vshader;
|
||||||
IWineD3DPixelShader *pshader;
|
IWineD3DPixelShader *pshader;
|
||||||
struct ps_compile_args ps_args;
|
struct ps_compile_args ps_args;
|
||||||
|
struct vs_compile_args vs_args;
|
||||||
} glsl_program_key_t;
|
} 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)
|
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;
|
entry->constant_version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +486,7 @@ static void shader_glsl_load_constants(
|
||||||
char useVertexShader) {
|
char useVertexShader) {
|
||||||
|
|
||||||
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
|
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;
|
IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
|
||||||
const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
|
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)
|
static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
|
||||||
{
|
{
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
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;
|
struct constant_heap *heap = &priv->vconst_heap;
|
||||||
UINT i;
|
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)
|
static void shader_glsl_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
|
||||||
{
|
{
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
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;
|
struct constant_heap *heap = &priv->pconst_heap;
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
|
@ -1030,7 +1032,7 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
|
||||||
strcpy(tmpStr, "gl_SecondaryColor");
|
strcpy(tmpStr, "gl_SecondaryColor");
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
sprintf(tmpStr, "attrib%u", reg);
|
||||||
}
|
}
|
||||||
break;
|
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 = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
|
||||||
key->vshader = entry->vshader;
|
key->vshader = entry->vshader;
|
||||||
key->pshader = entry->pshader;
|
key->pshader = entry->pshader;
|
||||||
|
key->vs_args = entry->vs_args;
|
||||||
key->ps_args = entry->ps_args;
|
key->ps_args = entry->ps_args;
|
||||||
|
|
||||||
hash_table_put(priv->glsl_program_lookup, key, entry);
|
hash_table_put(priv->glsl_program_lookup, key, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv,
|
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;
|
glsl_program_key_t key;
|
||||||
|
|
||||||
key.vshader = vshader;
|
key.vshader = vshader;
|
||||||
key.pshader = pshader;
|
key.pshader = pshader;
|
||||||
|
key.vs_args = *vs_args;
|
||||||
key.ps_args = *ps_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,
|
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 = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
|
||||||
key->vshader = entry->vshader;
|
key->vshader = entry->vshader;
|
||||||
key->pshader = entry->pshader;
|
key->pshader = entry->pshader;
|
||||||
|
key->vs_args = entry->vs_args;
|
||||||
key->ps_args = entry->ps_args;
|
key->ps_args = entry->ps_args;
|
||||||
hash_table_remove(priv->glsl_program_lookup, key);
|
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));
|
ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
|
||||||
checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
|
checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
|
||||||
GL_EXTCALL(glShaderSourceARB(ret, 1, (const char**)&buffer.buffer, NULL));
|
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));
|
GL_EXTCALL(glCompileShaderARB(ret));
|
||||||
checkGLcall("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) {
|
static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
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;
|
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
||||||
IWineD3DPixelShader *pshader = This->stateBlock->pixelShader;
|
IWineD3DPixelShader *pshader = This->stateBlock->pixelShader;
|
||||||
IWineD3DVertexShader *vshader = This->stateBlock->vertexShader;
|
IWineD3DVertexShader *vshader = This->stateBlock->vertexShader;
|
||||||
|
@ -3293,21 +3299,22 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
|
||||||
int i;
|
int i;
|
||||||
char glsl_name[8];
|
char glsl_name[8];
|
||||||
GLhandleARB vshader_id, pshader_id;
|
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) {
|
if(use_vs) {
|
||||||
IWineD3DVertexShaderImpl_CompileShader(vshader);
|
find_vs_compile_args((IWineD3DVertexShaderImpl*)This->stateBlock->vertexShader, This->stateBlock, &vs_compile_args);
|
||||||
vshader_id = ((IWineD3DVertexShaderImpl*)vshader)->prgId;
|
|
||||||
} else {
|
|
||||||
vshader_id = 0;
|
|
||||||
}
|
|
||||||
if(use_ps) {
|
|
||||||
find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelShader, This->stateBlock, &compile_args);
|
|
||||||
} else {
|
} else {
|
||||||
/* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
|
/* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
|
||||||
memset(&compile_args, 0, sizeof(compile_args));
|
memset(&vs_compile_args, 0, sizeof(vs_compile_args));
|
||||||
}
|
}
|
||||||
entry = get_glsl_program_entry(priv, vshader_id, pshader, &compile_args);
|
if(use_ps) {
|
||||||
|
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(&ps_compile_args, 0, sizeof(ps_compile_args));
|
||||||
|
}
|
||||||
|
entry = get_glsl_program_entry(priv, vshader, pshader, &vs_compile_args, &ps_compile_args);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
priv->glsl_program = entry;
|
priv->glsl_program = entry;
|
||||||
return;
|
return;
|
||||||
|
@ -3320,9 +3327,10 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
|
||||||
/* Create the entry */
|
/* Create the entry */
|
||||||
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
|
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
|
||||||
entry->programId = programId;
|
entry->programId = programId;
|
||||||
entry->vshader = vshader_id;
|
entry->vshader = vshader;
|
||||||
entry->pshader = pshader;
|
entry->pshader = pshader;
|
||||||
entry->ps_args = compile_args;
|
entry->vs_args = vs_compile_args;
|
||||||
|
entry->ps_args = ps_compile_args;
|
||||||
entry->constant_version = 0;
|
entry->constant_version = 0;
|
||||||
/* Add the hash table entry */
|
/* Add the hash table entry */
|
||||||
add_glsl_program_entry(priv, 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 */
|
/* Set the current program */
|
||||||
priv->glsl_program = entry;
|
priv->glsl_program = entry;
|
||||||
|
|
||||||
|
if(use_vs) {
|
||||||
|
vshader_id = find_gl_vshader((IWineD3DVertexShaderImpl *) vshader, &vs_compile_args);
|
||||||
|
} else {
|
||||||
|
vshader_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Attach GLSL vshader */
|
/* Attach GLSL vshader */
|
||||||
if (vshader_id) {
|
if (vshader_id) {
|
||||||
int max_attribs = 16; /* TODO: Will this always be the case? It is at the moment... */
|
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) {
|
if(use_ps) {
|
||||||
pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &compile_args);
|
pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args);
|
||||||
} else {
|
} else {
|
||||||
pshader_id = 0;
|
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) {
|
static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
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;
|
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
||||||
GLhandleARB program_id = 0;
|
GLhandleARB program_id = 0;
|
||||||
GLenum old_vertex_color_clamp, current_vertex_color_clamp;
|
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) {
|
static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
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];
|
GLhandleARB *blt_program = &priv->depth_blt_program[tex_type];
|
||||||
|
|
||||||
if (!*blt_program) {
|
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) {
|
static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
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;
|
GLhandleARB program_id;
|
||||||
|
|
||||||
program_id = priv->glsl_program ? priv->glsl_program->programId : 0;
|
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;
|
const struct list *linked_programs;
|
||||||
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
|
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
|
||||||
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
|
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;
|
const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
|
||||||
IWineD3DPixelShaderImpl *ps = NULL;
|
IWineD3DPixelShaderImpl *ps = NULL;
|
||||||
IWineD3DVertexShaderImpl *vs = NULL;
|
IWineD3DVertexShaderImpl *vs = NULL;
|
||||||
|
@ -3619,7 +3633,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
|
||||||
if(ps->num_gl_shaders == 0) return;
|
if(ps->num_gl_shaders == 0) return;
|
||||||
} else {
|
} else {
|
||||||
vs = (IWineD3DVertexShaderImpl *) This;
|
vs = (IWineD3DVertexShaderImpl *) This;
|
||||||
if(vs->prgId == 0) return;
|
if(vs->num_gl_shaders == 0) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
linked_programs = &This->baseShader.linked_programs;
|
linked_programs = &This->baseShader.linked_programs;
|
||||||
|
@ -3652,22 +3666,29 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
|
||||||
HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
|
HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
|
||||||
ps->gl_shaders = NULL;
|
ps->gl_shaders = NULL;
|
||||||
ps->num_gl_shaders = 0;
|
ps->num_gl_shaders = 0;
|
||||||
|
ps->shader_array_size = 0;
|
||||||
} else {
|
} else {
|
||||||
TRACE("Deleting shader object %u\n", vs->prgId);
|
UINT i;
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
GL_EXTCALL(glDeleteObjectARB(vs->prgId));
|
for(i = 0; i < vs->num_gl_shaders; i++) {
|
||||||
checkGLcall("glDeleteObjectARB");
|
TRACE("deleting vshader %u\n", vs->gl_shaders[i].prgId);
|
||||||
|
GL_EXTCALL(glDeleteObjectARB(vs->gl_shaders[i].prgId));
|
||||||
|
checkGLcall("glDeleteObjectARB");
|
||||||
|
}
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
vs->prgId = 0;
|
HeapFree(GetProcessHeap(), 0, vs->gl_shaders);
|
||||||
vs->baseShader.is_compiled = FALSE;
|
vs->gl_shaders = NULL;
|
||||||
|
vs->num_gl_shaders = 0;
|
||||||
|
vs->shader_array_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int glsl_program_key_hash(const void *key)
|
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 << 15);
|
||||||
hash ^= (hash >> 10);
|
hash ^= (hash >> 10);
|
||||||
hash += (hash << 3);
|
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)
|
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 *ka = keya;
|
||||||
const glsl_program_key_t *kb = (const glsl_program_key_t *)keyb;
|
const glsl_program_key_t *kb = keyb;
|
||||||
|
|
||||||
return ka->vshader == kb->vshader && ka->pshader == kb->pshader &&
|
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)
|
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) {
|
static void shader_glsl_free(IWineD3DDevice *iface) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
|
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < tex_type_count; ++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);
|
shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
|
||||||
break;
|
break;
|
||||||
case FOG_EXP:
|
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;
|
break;
|
||||||
case FOG_EXP2:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3869,7 +3897,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
|
||||||
return shader_obj;
|
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;
|
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||||
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
|
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
|
||||||
CONST DWORD *function = This->baseShader.function;
|
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");
|
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");
|
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 */
|
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
|
||||||
if (!reg_maps->fog)
|
* 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");
|
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.
|
/* Write the final position.
|
||||||
*
|
*
|
||||||
|
@ -3919,8 +3954,7 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
|
||||||
GL_EXTCALL(glCompileShaderARB(shader_obj));
|
GL_EXTCALL(glCompileShaderARB(shader_obj));
|
||||||
print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
|
print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
|
||||||
|
|
||||||
/* Store the shader object */
|
return shader_obj;
|
||||||
This->prgId = shader_obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
|
static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
|
||||||
|
|
|
@ -34,8 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
||||||
|
|
||||||
#define GLINFO_LOCATION ((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info
|
#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) {
|
static HRESULT WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) {
|
||||||
TRACE("iface %p, riid %s, ppobj %p\n", iface, debugstr_guid(riid), 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);
|
retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args);
|
||||||
shader_buffer_free(&buffer);
|
shader_buffer_free(&buffer);
|
||||||
|
|
||||||
This->baseShader.is_compiled = TRUE;
|
|
||||||
|
|
||||||
return retval;
|
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)
|
GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
|
||||||
{
|
{
|
||||||
UINT i;
|
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),
|
/* 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++) {
|
for(i = 0; i < shader->num_gl_shaders; i++) {
|
||||||
if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) {
|
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");
|
TRACE("No matching GL shader found, compiling a new shader\n");
|
||||||
old_array = shader->gl_shaders;
|
if(shader->shader_array_size == shader->num_gl_shaders) {
|
||||||
if(old_array) {
|
if(shader->gl_shaders) {
|
||||||
shader->gl_shaders = HeapReAlloc(GetProcessHeap(), 0, old_array,
|
new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2);
|
||||||
(shader->num_gl_shaders + 1) * sizeof(*shader->gl_shaders));
|
new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders,
|
||||||
} else {
|
new_size * sizeof(*shader->gl_shaders));
|
||||||
shader->gl_shaders = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
|
} else {
|
||||||
}
|
new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
|
||||||
|
new_size = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(!shader->gl_shaders) {
|
if(!new_array) {
|
||||||
ERR("Out of memory\n");
|
ERR("Out of memory\n");
|
||||||
return 0;
|
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].args = *args;
|
||||||
|
|
|
@ -133,7 +133,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
case WINED3DQUERYTYPE_VCACHE:
|
case WINED3DQUERYTYPE_VCACHE:
|
||||||
{
|
{
|
||||||
|
|
||||||
WINED3DDEVINFO_VCACHE *data = (WINED3DDEVINFO_VCACHE *)pData;
|
WINED3DDEVINFO_VCACHE *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
data->Pattern = WINEMAKEFOURCC('C','A','C','H');
|
data->Pattern = WINEMAKEFOURCC('C','A','C','H');
|
||||||
|
@ -145,7 +145,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_RESOURCEMANAGER:
|
case WINED3DQUERYTYPE_RESOURCEMANAGER:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_RESOURCEMANAGER *data = (WINED3DDEVINFO_RESOURCEMANAGER *)pData;
|
WINED3DDEVINFO_RESOURCEMANAGER *data = pData;
|
||||||
int i;
|
int i;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
|
@ -169,7 +169,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_VERTEXSTATS:
|
case WINED3DQUERYTYPE_VERTEXSTATS:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_VERTEXSTATS *data = (WINED3DDEVINFO_VERTEXSTATS *)pData;
|
WINED3DDEVINFO_VERTEXSTATS *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
data->NumRenderedTriangles = 1;
|
data->NumRenderedTriangles = 1;
|
||||||
|
@ -203,7 +203,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_PIPELINETIMINGS:
|
case WINED3DQUERYTYPE_PIPELINETIMINGS:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_PIPELINETIMINGS *data = (WINED3DDEVINFO_PIPELINETIMINGS *)pData;
|
WINED3DDEVINFO_PIPELINETIMINGS *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_INTERFACETIMINGS:
|
case WINED3DQUERYTYPE_INTERFACETIMINGS:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_INTERFACETIMINGS *data = (WINED3DDEVINFO_INTERFACETIMINGS *)pData;
|
WINED3DDEVINFO_INTERFACETIMINGS *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
|
||||||
|
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
|
@ -229,7 +229,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_VERTEXTIMINGS:
|
case WINED3DQUERYTYPE_VERTEXTIMINGS:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
|
WINED3DDEVINFO_STAGETIMINGS *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
|
||||||
|
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
|
@ -240,7 +240,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_PIXELTIMINGS:
|
case WINED3DQUERYTYPE_PIXELTIMINGS:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
|
WINED3DDEVINFO_STAGETIMINGS *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
|
||||||
|
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
|
@ -250,7 +250,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
|
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_BANDWIDTHTIMINGS *data = (WINED3DDEVINFO_BANDWIDTHTIMINGS *)pData;
|
WINED3DDEVINFO_BANDWIDTHTIMINGS *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
|
||||||
|
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
|
@ -263,7 +263,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
|
||||||
break;
|
break;
|
||||||
case WINED3DQUERYTYPE_CACHEUTILIZATION:
|
case WINED3DQUERYTYPE_CACHEUTILIZATION:
|
||||||
{
|
{
|
||||||
WINED3DDEVINFO_CACHEUTILIZATION *data = (WINED3DDEVINFO_CACHEUTILIZATION *)pData;
|
WINED3DDEVINFO_CACHEUTILIZATION *data = pData;
|
||||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
|
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
|
||||||
|
|
||||||
if(pData == NULL || dwSize == 0) break;
|
if(pData == NULL || dwSize == 0) break;
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "wined3d_private.h"
|
#include "wined3d_private.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
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,
|
HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYPE resource_type,
|
||||||
IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
|
IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
|
||||||
|
|
|
@ -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
|
* and 2) disables the fog computation (in either the fixed function or programmable
|
||||||
* rasterizer) if using a vertex program.
|
* 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
|
* If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
|
||||||
* without shaders).
|
* 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,
|
/* 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."
|
* the system will apply only pixel(=table) fog effects."
|
||||||
*/
|
*/
|
||||||
else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||||
context->last_was_foggy_shader = FALSE;
|
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 */
|
||||||
|
|
||||||
switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
case WINED3DFOG_EXP2:
|
||||||
/* If processed vertices are used, fall through to the NONE case */
|
if(!context->last_was_rhw) {
|
||||||
case WINED3DFOG_EXP:
|
glFogi(GL_FOG_MODE, GL_EXP2);
|
||||||
if(!context->last_was_rhw) {
|
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
|
||||||
glFogi(GL_FOG_MODE, GL_EXP);
|
new_source = FOGSOURCE_FFP;
|
||||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
|
break;
|
||||||
new_source = FOGSOURCE_FFP;
|
}
|
||||||
break;
|
/* drop through */
|
||||||
}
|
|
||||||
/* drop through */
|
|
||||||
|
|
||||||
case WINED3DFOG_EXP2:
|
case WINED3DFOG_LINEAR:
|
||||||
if(!context->last_was_rhw) {
|
if(!context->last_was_rhw) {
|
||||||
glFogi(GL_FOG_MODE, GL_EXP2);
|
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
|
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
|
||||||
new_source = FOGSOURCE_FFP;
|
new_source = FOGSOURCE_FFP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* drop through */
|
/* drop through */
|
||||||
|
|
||||||
case WINED3DFOG_LINEAR:
|
case WINED3DFOG_NONE:
|
||||||
if(!context->last_was_rhw) {
|
/* 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);
|
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||||
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
|
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
|
||||||
new_source = FOGSOURCE_FFP;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
/* drop through */
|
|
||||||
|
|
||||||
case WINED3DFOG_NONE:
|
default:
|
||||||
/* Both are none? According to msdn the alpha channel of the specular
|
FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
|
||||||
* color contains a fog factor. Set it in drawStridedSlow.
|
new_source = FOGSOURCE_FFP; /* Make the compiler happy */
|
||||||
* 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 */
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
glHint(GL_FOG_HINT, GL_NICEST);
|
|
||||||
checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
|
|
||||||
context->last_was_foggy_shader = FALSE;
|
|
||||||
new_source = FOGSOURCE_FFP;
|
new_source = FOGSOURCE_FFP;
|
||||||
|
|
||||||
switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
|
switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
|
||||||
|
@ -3928,8 +3925,18 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
|
||||||
case WINED3DDECLTYPE_UBYTE4:
|
case WINED3DDECLTYPE_UBYTE4:
|
||||||
GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
|
GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
|
||||||
break;
|
break;
|
||||||
case WINED3DDECLTYPE_UBYTE4N:
|
|
||||||
case WINED3DDECLTYPE_D3DCOLOR:
|
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));
|
GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -4270,10 +4277,12 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
|
||||||
load_numbered = TRUE;
|
load_numbered = TRUE;
|
||||||
device->useDrawStridedSlow = FALSE;
|
device->useDrawStridedSlow = FALSE;
|
||||||
}
|
}
|
||||||
} else if (fixup || GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) ||
|
} else if (fixup || (!dataLocations->u.s.pSize.lpData
|
||||||
(dataLocations->u.s.pSize.lpData == NULL &&
|
&& !dataLocations->position_transformed
|
||||||
dataLocations->u.s.diffuse.lpData == NULL &&
|
&& (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA)
|
||||||
dataLocations->u.s.specular.lpData == NULL)) {
|
|| (!dataLocations->u.s.diffuse.lpData
|
||||||
|
&& !dataLocations->u.s.specular.lpData))))
|
||||||
|
{
|
||||||
/* Load the vertex data using named arrays */
|
/* Load the vertex data using named arrays */
|
||||||
load_named = TRUE;
|
load_named = TRUE;
|
||||||
device->useDrawStridedSlow = FALSE;
|
device->useDrawStridedSlow = FALSE;
|
||||||
|
@ -4331,15 +4340,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
||||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||||
BOOL wasrhw = context->last_was_rhw;
|
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;
|
transformed = device->strided_streams.position_transformed;
|
||||||
if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
|
if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
|
||||||
updateFog = TRUE;
|
updateFog = TRUE;
|
||||||
|
@ -4405,8 +4405,11 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
||||||
state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
|
state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
|
if(context->last_was_vshader) {
|
||||||
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
|
updateFog = TRUE;
|
||||||
|
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
|
||||||
|
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
|
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
|
||||||
state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
|
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);
|
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateFog = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2228,7 +2228,7 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
|
||||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader));
|
GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader));
|
||||||
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 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);
|
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
#include "wined3d_private.h"
|
#include "wined3d_private.h"
|
||||||
#include "float.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -46,7 +45,7 @@ static inline unsigned short float_32_to_16(const float *in)
|
||||||
/* Deal with special numbers */
|
/* Deal with special numbers */
|
||||||
if(*in == 0.0) return 0x0000;
|
if(*in == 0.0) return 0x0000;
|
||||||
if(isnan(*in)) return 0x7C01;
|
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)) {
|
if(tmp < pow(2, 10)) {
|
||||||
do
|
do
|
||||||
|
@ -1145,7 +1144,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D
|
||||||
assert(width <= dlock.Pitch);
|
assert(width <= dlock.Pitch);
|
||||||
|
|
||||||
if (DestRect && Src != This)
|
if (DestRect && Src != This)
|
||||||
dbuf = (BYTE*)dlock.pBits;
|
dbuf = dlock.pBits;
|
||||||
else
|
else
|
||||||
dbuf = (BYTE*)dlock.pBits+(xdst.top*dlock.Pitch)+(xdst.left*bpp);
|
dbuf = (BYTE*)dlock.pBits+(xdst.top*dlock.Pitch)+(xdst.left*bpp);
|
||||||
|
|
||||||
|
|
|
@ -1365,8 +1365,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B
|
||||||
}
|
}
|
||||||
#undef GLINFO_LOCATION
|
#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 */
|
/* This small helper function is used to convert a bitmask into the number of masked bits */
|
||||||
unsigned int count_bits(unsigned int mask)
|
unsigned int count_bits(unsigned int mask)
|
||||||
{
|
{
|
||||||
|
@ -1457,8 +1455,6 @@ BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef GLINFO_LOCATION
|
|
||||||
|
|
||||||
/* DirectDraw stuff */
|
/* DirectDraw stuff */
|
||||||
WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
|
WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
|
||||||
switch(depth) {
|
switch(depth) {
|
||||||
|
@ -2096,17 +2092,21 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
|
||||||
if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
|
if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
|
||||||
settings->fog = FOG_OFF;
|
settings->fog = FOG_OFF;
|
||||||
} else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
} else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||||
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
|
||||||
case WINED3DFOG_NONE:
|
settings->fog = FOG_LINEAR;
|
||||||
case WINED3DFOG_LINEAR:
|
} else {
|
||||||
settings->fog = FOG_LINEAR;
|
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
||||||
break;
|
case WINED3DFOG_NONE:
|
||||||
case WINED3DFOG_EXP:
|
case WINED3DFOG_LINEAR:
|
||||||
settings->fog = FOG_EXP;
|
settings->fog = FOG_LINEAR;
|
||||||
break;
|
break;
|
||||||
case WINED3DFOG_EXP2:
|
case WINED3DFOG_EXP:
|
||||||
settings->fog = FOG_EXP2;
|
settings->fog = FOG_EXP;
|
||||||
break;
|
break;
|
||||||
|
case WINED3DFOG_EXP2:
|
||||||
|
settings->fog = FOG_EXP2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
|
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_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
|
||||||
const struct ffp_frag_settings *settings)
|
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) {
|
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)
|
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;
|
unsigned int hash = 0, i;
|
||||||
const DWORD *blob;
|
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)
|
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 *ka = keya;
|
||||||
const struct ffp_frag_settings *kb = (const struct ffp_frag_settings *)keyb;
|
const struct ffp_frag_settings *kb = keyb;
|
||||||
|
|
||||||
return memcmp(ka, kb, sizeof(*ka)) == 0;
|
return memcmp(ka, kb, sizeof(*ka)) == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
/* 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 */
|
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[] = {
|
CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
||||||
/* This table is not order or position dependent. */
|
/* This table is not order or position dependent. */
|
||||||
|
|
||||||
|
@ -218,21 +216,6 @@ BOOL vshader_get_input(
|
||||||
return FALSE;
|
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
|
IWineD3DVertexShader IUnknown parts follow
|
||||||
******************************************* */
|
******************************************* */
|
||||||
|
@ -418,40 +401,20 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
|
static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct vs_compile_args *args) {
|
||||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
|
||||||
CONST DWORD *function = This->baseShader.function;
|
|
||||||
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
|
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
|
||||||
|
SHADER_BUFFER buffer;
|
||||||
TRACE("(%p) : function %p\n", iface, function);
|
GLuint ret;
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate the HW shader */
|
/* Generate the HW shader */
|
||||||
TRACE("(%p) : Generating hardware program\n", This);
|
TRACE("(%p) : Generating hardware program\n", This);
|
||||||
IWineD3DVertexShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function);
|
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);
|
||||||
|
|
||||||
This->baseShader.is_compiled = TRUE;
|
return ret;
|
||||||
|
|
||||||
return WINED3D_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
|
const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
|
||||||
|
@ -470,3 +433,56 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
|
||||||
IWineD3DVertexShaderImpl_FakeSemantics,
|
IWineD3DVertexShaderImpl_FakeSemantics,
|
||||||
IWIneD3DVertexShaderImpl_SetLocalConstantsF
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -3257,6 +3257,7 @@ typedef enum _GL_Cards {
|
||||||
CARD_ATI_RADEON_7200 = 0x5144,
|
CARD_ATI_RADEON_7200 = 0x5144,
|
||||||
CARD_ATI_RADEON_8500 = 0x514c,
|
CARD_ATI_RADEON_8500 = 0x514c,
|
||||||
CARD_ATI_RADEON_9500 = 0x4144,
|
CARD_ATI_RADEON_9500 = 0x4144,
|
||||||
|
CARD_ATI_RADEON_XPRESS_200M = 0x5955,
|
||||||
CARD_ATI_RADEON_X700 = 0x5e4c,
|
CARD_ATI_RADEON_X700 = 0x5e4c,
|
||||||
CARD_ATI_RADEON_X1600 = 0x71c2,
|
CARD_ATI_RADEON_X1600 = 0x71c2,
|
||||||
CARD_ATI_RADEON_HD2300 = 0x7210,
|
CARD_ATI_RADEON_HD2300 = 0x7210,
|
||||||
|
|
|
@ -461,6 +461,18 @@ struct ps_compile_args {
|
||||||
/* Texture types(2D, Cube, 3D) in ps 1.x */
|
/* 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 {
|
typedef struct {
|
||||||
const SHADER_HANDLER *shader_instruction_handler_table;
|
const SHADER_HANDLER *shader_instruction_handler_table;
|
||||||
void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
|
void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
|
||||||
|
@ -475,7 +487,7 @@ typedef struct {
|
||||||
void (*shader_free_private)(IWineD3DDevice *iface);
|
void (*shader_free_private)(IWineD3DDevice *iface);
|
||||||
BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
|
BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
|
||||||
GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args);
|
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);
|
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);
|
BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
|
||||||
} shader_backend_t;
|
} 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_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */
|
||||||
WORD last_was_pshader : 1;
|
WORD last_was_pshader : 1;
|
||||||
WORD last_was_vshader : 1;
|
WORD last_was_vshader : 1;
|
||||||
WORD last_was_foggy_shader : 1;
|
|
||||||
WORD namedArraysLoaded : 1;
|
WORD namedArraysLoaded : 1;
|
||||||
WORD numberedArraysLoaded : 1;
|
WORD numberedArraysLoaded : 1;
|
||||||
WORD last_was_blit : 1;
|
WORD last_was_blit : 1;
|
||||||
|
@ -813,7 +824,7 @@ struct WineD3DContext {
|
||||||
WORD isPBuffer : 1;
|
WORD isPBuffer : 1;
|
||||||
WORD fog_enabled : 1;
|
WORD fog_enabled : 1;
|
||||||
WORD num_untracked_materials : 2; /* Max value 2 */
|
WORD num_untracked_materials : 2; /* Max value 2 */
|
||||||
WORD padding : 2;
|
WORD padding : 3;
|
||||||
BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
|
BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
|
||||||
BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
|
BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
|
||||||
DWORD numbered_array_mask;
|
DWORD numbered_array_mask;
|
||||||
|
@ -2210,7 +2221,6 @@ typedef struct IWineD3DBaseShaderClass
|
||||||
CONST SHADER_OPCODE *shader_ins;
|
CONST SHADER_OPCODE *shader_ins;
|
||||||
DWORD *function;
|
DWORD *function;
|
||||||
UINT functionLength;
|
UINT functionLength;
|
||||||
BOOL is_compiled;
|
|
||||||
UINT cur_loop_depth, cur_loop_regno;
|
UINT cur_loop_depth, cur_loop_regno;
|
||||||
BOOL load_local_constsF;
|
BOOL load_local_constsF;
|
||||||
BOOL uses_bool_consts, uses_int_consts;
|
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 {
|
typedef struct IWineD3DVertexShaderImpl {
|
||||||
/* IUnknown parts*/
|
/* IUnknown parts*/
|
||||||
const IWineD3DVertexShaderVtbl *lpVtbl;
|
const IWineD3DVertexShaderVtbl *lpVtbl;
|
||||||
|
@ -2341,22 +2357,25 @@ typedef struct IWineD3DVertexShaderImpl {
|
||||||
DWORD usage;
|
DWORD usage;
|
||||||
|
|
||||||
/* The GL shader */
|
/* The GL shader */
|
||||||
GLuint prgId;
|
struct vs_compiled_shader *gl_shaders;
|
||||||
|
UINT num_gl_shaders, shader_array_size;
|
||||||
|
|
||||||
/* Vertex shader input and output semantics */
|
/* Vertex shader input and output semantics */
|
||||||
semantic semantics_in [MAX_ATTRIBS];
|
semantic semantics_in [MAX_ATTRIBS];
|
||||||
semantic semantics_out [MAX_REG_OUTPUT];
|
semantic semantics_out [MAX_REG_OUTPUT];
|
||||||
|
|
||||||
WORD swizzle_map; /* MAX_ATTRIBS, 16 */
|
|
||||||
|
|
||||||
UINT min_rel_offset, max_rel_offset;
|
UINT min_rel_offset, max_rel_offset;
|
||||||
UINT rel_offset;
|
UINT rel_offset;
|
||||||
|
|
||||||
UINT recompile_count;
|
UINT recompile_count;
|
||||||
|
|
||||||
|
const struct vs_compile_args *cur_args;
|
||||||
} IWineD3DVertexShaderImpl;
|
} IWineD3DVertexShaderImpl;
|
||||||
extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[];
|
extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[];
|
||||||
extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
|
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
|
* IDirect3DPixelShader implementation structure
|
||||||
|
@ -2384,7 +2403,7 @@ typedef struct IWineD3DPixelShaderImpl {
|
||||||
|
|
||||||
/* The GL shader */
|
/* The GL shader */
|
||||||
struct ps_compiled_shader *gl_shaders;
|
struct ps_compiled_shader *gl_shaders;
|
||||||
UINT num_gl_shaders;
|
UINT num_gl_shaders, shader_array_size;
|
||||||
|
|
||||||
/* Some information about the shader behavior */
|
/* Some information about the shader behavior */
|
||||||
struct stb_const_desc bumpenvmatconst[MAX_TEXTURES];
|
struct stb_const_desc bumpenvmatconst[MAX_TEXTURES];
|
||||||
|
|
Loading…
Reference in a new issue