IWineD3DVertexShader *wineD3DVertexShader;
};
+#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256
+
/* ------------------------ */
/* IDirect3DPixelShaderImpl */
if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
}
+ pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
TRACE("Returning %p %p\n", This, pCaps);
return hrc;
object->ref = 1;
EnterCriticalSection(&d3d8_cs);
hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
- wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, NULL, (IUnknown *)object);
+ wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
LeaveCriticalSection(&d3d8_cs);
if (FAILED(hrc)) {
object->ref = 1;
EnterCriticalSection(&d3d8_cs);
hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
- Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format), Pool,
- &object->wineD3DVolumeTexture, NULL, (IUnknown *)object);
+ Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
+ Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
LeaveCriticalSection(&d3d8_cs);
if (hrc != D3D_OK) {
object->ref = 1;
EnterCriticalSection(&d3d8_cs);
hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
- wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, NULL, (IUnknown *)object);
+ wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
LeaveCriticalSection(&d3d8_cs);
if (hr != D3D_OK){
object->ref = 1;
EnterCriticalSection(&d3d8_cs);
hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
- 0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL,
- (IUnknown *)object);
+ 0 /* fvf for ddraw only */, (WINED3DPOOL)Pool, &object->wineD3DVertexBuffer, (IUnknown *)object);
LeaveCriticalSection(&d3d8_cs);
object->fvf = FVF;
TRACE("Calling wined3d create index buffer\n");
EnterCriticalSection(&d3d8_cs);
hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
- (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer,
- NULL, (IUnknown *)object);
+ (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
LeaveCriticalSection(&d3d8_cs);
if (D3D_OK != hrc) {
EnterCriticalSection(&d3d8_cs);
hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
- (WINED3DPOOL)Pool, MultiSample,MultisampleQuality, NULL, SURFACE_OPENGL, (IUnknown *)object);
+ (WINED3DPOOL)Pool, MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
LeaveCriticalSection(&d3d8_cs);
if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
/* free up object */
HRESULT hr;
TRACE("(%p) : Relay\n", This);
+ if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
+ WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+ Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
EnterCriticalSection(&d3d8_cs);
hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
LeaveCriticalSection(&d3d8_cs);
HRESULT hr;
TRACE("(%p) : Relay\n", This);
+ if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
+ WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+ Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
EnterCriticalSection(&d3d8_cs);
hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
LeaveCriticalSection(&d3d8_cs);
EnterCriticalSection(&d3d8_cs);
hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction,
- &object->wineD3DPixelShader, (IUnknown *)object);
+ NULL, &object->wineD3DPixelShader, (IUnknown *)object);
if (FAILED(hr))
{
LeaveCriticalSection(&d3d8_cs);
object->lpVtbl = &Direct3DVolume8_Vtbl;
object->ref = 1;
hr = IWineD3DDevice_CreateVolume(This->WineD3DDevice, width, height, depth, usage,
- format, pool, &object->wineD3DVolume, NULL, (IUnknown *)object);
+ format, pool, &object->wineD3DVolume, (IUnknown *)object);
if (FAILED(hr))
{
ERR("(%p) CreateVolume failed, returning %#x\n", iface, hr);
if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
}
+ pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
TRACE("(%p) returning %p\n", This, pCaps);
return hrc;
object->ref = 1;
EnterCriticalSection(&d3d9_cs);
hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage,
- wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture,
- pSharedHandle, (IUnknown*)object);
+ wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
if (hr != D3D_OK){
LPDIRECT3DDEVICE9EX parentDevice;
} IDirect3DVertexShader9Impl;
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
+
/* --------------------- */
/* IDirect3DPixelShader9 */
/* --------------------- */
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
- Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
- MultiSample, MultisampleQuality, pSharedHandle, SURFACE_OPENGL, (IUnknown *)object);
+ Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
+ (WINED3DPOOL)Pool, MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
object->lpVtbl = &Direct3DVolume9_Vtbl;
object->ref = 1;
hr = IWineD3DDevice_CreateVolume(This->WineD3DDevice, width, height, depth, usage & WINED3DUSAGE_MASK,
- format, pool, &object->wineD3DVolume, NULL, (IUnknown *)object);
+ format, pool, &object->wineD3DVolume, (IUnknown *)object);
if (FAILED(hr))
{
ERR("(%p) CreateVolume failed, returning %#x\n", iface, hr);
D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP |
D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP |
D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
+
+ pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
}
static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) {
TRACE("Calling wined3d create index buffer\n");
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
- (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer,
- pSharedHandle, (IUnknown *)object);
+ (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
if (hrc != D3D_OK) {
object->ref = 1;
object->lpVtbl = &Direct3DPixelShader9_Vtbl;
EnterCriticalSection(&d3d9_cs);
- hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, &object->wineD3DPixelShader , (IUnknown *)object);
+ hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, NULL,
+ &object->wineD3DPixelShader, (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
if (hrc != D3D_OK) {
object->ref = 1;
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
- wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, pSharedHandle, (IUnknown *)object);
+ wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
if (FAILED(hrc)) {
object->fvf = FVF;
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
- 0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer),
- pSharedHandle, (IUnknown *)object);
+ 0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
if (hrc != D3D_OK) {
HRESULT hr;
TRACE("(%p) : Relay\n", This);
+ if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) {
+ WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+ Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
EnterCriticalSection(&d3d9_cs);
hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
LeaveCriticalSection(&d3d9_cs);
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
+ if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) {
+ WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+ Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
TRACE("(%p) : Relay\n", This);
EnterCriticalSection(&d3d9_cs);
hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
- Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format), Pool,
- &object->wineD3DVolumeTexture, pSharedHandle, (IUnknown *)object);
+ Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
+ Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
+++ /dev/null
-/* A few helpful macros for implementing COM objects.
- *
- * Copyright 2000 TransGaming Technologies Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef _DDCOMIMPL_H_
-#define _DDCOMIMPL_H_
-
-#include <stddef.h>
-
-/* Generates the name for a vtable pointer for a given interface. */
-/* The canonical name for a single interface is "lpVtbl". */
-#define ICOM_VFIELD_MULTI_NAME2(iface) ITF_##iface
-#define ICOM_VFIELD_MULTI_NAME(iface) ICOM_VFIELD_MULTI_NAME2(iface)
-
-/* Declares a vtable pointer field in an implementation. */
-#define ICOM_VFIELD_MULTI(iface) \
- iface ICOM_VFIELD_MULTI_NAME(iface)
-
-/* Returns the offset of a vtable pointer within an implementation object. */
-#define ICOM_VFIELD_OFFSET(impltype, iface) \
- offsetof(impltype, ICOM_VFIELD_MULTI_NAME(iface))
-
-/* Given an interface pointer, returns the implementation pointer. */
-#define ICOM_OBJECT(impltype, ifacename, ifaceptr) \
- (impltype*)((ifaceptr) == NULL ? NULL \
- : (char*)(ifaceptr) - ICOM_VFIELD_OFFSET(impltype,ifacename))
-
-#define ICOM_THIS_FROM(impltype, ifacename, ifaceptr) \
- impltype* This = ICOM_OBJECT(impltype, ifacename, ifaceptr)
-
-/* Given an object and interface name, returns a pointer to that interface. */
-#define ICOM_INTERFACE(implobj, iface) \
- (implobj == NULL ? NULL :&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))
-
-#define ICOM_INIT_INTERFACE(implobj, ifacename, vtblname) \
- do { \
- (implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).lpVtbl = &(vtblname); \
- } while (0)
-
-#define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr) \
- ICOM_INTERFACE(ICOM_OBJECT(impltype, ifnamefrom, ifaceptr), ifnameto)
-
-#endif /* _DDCOMIMPL_H_ */
}
/* Create the new surface */
- hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
- Width, Height, Format,
- TRUE /* Lockable */,
- FALSE /* Discard */,
- surfImpl->mipmap_level,
- &surfImpl->WineD3DSurface,
- Type,
- Usage,
- Pool,
- MultiSampleType,
- MultiSampleQuality,
- 0 /* SharedHandle */,
- This->ImplType,
- Parent);
+ hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, Width, Height, Format,
+ TRUE /* Lockable */, FALSE /* Discard */, surfImpl->mipmap_level, &surfImpl->WineD3DSurface,
+ Type, Usage, Pool, MultiSampleType, MultiSampleQuality, This->ImplType, Parent);
if(hr != D3D_OK)
return hr;
}
/* Now create the WineD3D Surface */
- hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
- pDDSD->dwWidth,
- pDDSD->dwHeight,
- Format,
- TRUE /* Lockable */,
- FALSE /* Discard */,
- level,
- &(*ppSurf)->WineD3DSurface,
- ResType, Usage,
- Pool,
- WINED3DMULTISAMPLE_NONE,
- 0 /* MultiSampleQuality */,
- 0 /* SharedHandle */,
- ImplType,
- Parent);
+ hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, pDDSD->dwWidth, pDDSD->dwHeight, Format,
+ TRUE /* Lockable */, FALSE /* Discard */, level, &(*ppSurf)->WineD3DSurface, ResType, Usage,
+ Pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, ImplType, Parent);
if(hr != D3D_OK)
{
*/
if(desc2.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
{
- hr = IWineD3DDevice_CreateCubeTexture(This->wineD3DDevice, DDSD->dwWidth /* Edgelength */,
- levels, 0 /* usage */, Format, Pool, (IWineD3DCubeTexture **)&object->wineD3DTexture,
- 0 /* SharedHandle */, (IUnknown *)object);
+ hr = IWineD3DDevice_CreateCubeTexture(This->wineD3DDevice, DDSD->dwWidth /* Edgelength */, levels,
+ 0 /* usage */, Format, Pool, (IWineD3DCubeTexture **)&object->wineD3DTexture, (IUnknown *)object);
}
else
{
hr = IWineD3DDevice_CreateTexture(This->wineD3DDevice, DDSD->dwWidth, DDSD->dwHeight, levels,
- 0 /* usage */, Format, Pool, (IWineD3DTexture **) &object->wineD3DTexture,
- 0 /* SharedHandle */, (IUnknown *)object);
+ 0 /* usage */, Format, Pool, (IWineD3DTexture **)&object->wineD3DTexture, (IUnknown *)object);
}
This->tex_root = NULL;
}
* The return value consist of a combination of D3DCLIP_* flags, or it's
* 0 if the sphere is completely visible(according to the SDK, not checked)
*
- * Sounds like an overdose of math ;)
- *
* Version 3 and 7
*
* Params:
* ReturnValues: Array to write the results to
*
* Returns:
- * D3D_OK because it's a stub
+ * D3D_OK
* (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
* (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
* is singular)
* takes the pointer and avoids the memcpy
*/
hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, 0x40000 /* Length. Don't know how long it should be */,
- WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT,
- &object->indexbuffer, 0 /* Handle */, (IUnknown *)IndexBufferParent);
+ WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &object->indexbuffer, (IUnknown *)IndexBufferParent);
if(FAILED(hr))
{
EnterCriticalSection(&ddraw_cs);
hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice,
- get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices,
- Desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0,
- Desc->dwFVF,
- Desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT,
- &object->wineD3DVertexBuffer,
- 0 /* SharedHandle */,
- (IUnknown *)object);
+ get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices,
+ Desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0, Desc->dwFVF,
+ Desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT,
+ &object->wineD3DVertexBuffer, (IUnknown *)object);
if(hr != D3D_OK)
{
ERR("(%p) IWineD3DDevice::CreateVertexBuffer failed with hr=%08x\n", This, hr);
/* Add the light in the 'linked' chain */
lpDirect3DLightImpl->next = This->lights;
This->lights = lpDirect3DLightImpl;
+ IDirect3DLight_AddRef(lpDirect3DLight);
/* Attach the light to the viewport */
lpDirect3DLightImpl->active_viewport = This;
else prev_light->next = cur_light->next;
/* Detach the light to the viewport */
cur_light->active_viewport = NULL;
+ IDirect3DLight_Release( (IDirect3DLight *)cur_light );
This->num_lights--;
This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
LeaveCriticalSection(&ddraw_cs);
break;
}
+ if (*lplpDirect3DLight)
+ IDirect3DLight_AddRef(*lplpDirect3DLight);
+
LeaveCriticalSection(&ddraw_cs);
return *lplpDirect3DLight ? D3D_OK : DDERR_INVALIDPARAMS;
* Copyright 2006 Jason Green
* Copyright 2006 Henri Verbeet
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info,
GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
{
- DWORD shader_version = This->baseShader.reg_maps.shader_version;
local_constant* lconst;
DWORD i, j;
unsigned int ret;
}
}
/* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
- if (target_type == GL_FRAGMENT_PROGRAM_ARB && WINED3DSHADER_VERSION_MAJOR(shader_version) == 1)
+ if (target_type == GL_FRAGMENT_PROGRAM_ARB && This->baseShader.reg_maps.shader_version.major == 1)
{
float lcl_const[4];
for(i = 0; i < max_constants; i++) {
This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count + 1);
}
+static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
+{
+ DWORD *ret;
+ DWORD idx = 0;
+ const local_constant *lconst;
+
+ if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) return NULL;
+
+ ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * This->baseShader.limits.temporary);
+ if(!ret) {
+ ERR("Out of memory\n");
+ return NULL;
+ }
+
+ LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
+ ret[lconst->idx] = idx++;
+ }
+ return ret;
+}
+
/* Generate the variable & register declarations for the ARB_vertex_program output target */
static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
- SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
+ SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info, DWORD *lconst_map)
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
DWORD i, cur;
- char pshader = shader_is_pshader_version(reg_maps->shader_version);
+ char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
unsigned max_constantsF = min(This->baseShader.limits.constant_float,
(pshader ? GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS :
GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS));
}
if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] && pshader) {
- shader_addline(buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
- srgb_mul_low, srgb_mul_low, srgb_mul_low);
- shader_addline(buffer, "PARAM srgb_comparison = {%f, %f, %f, %f};\n",
- srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
- shader_addline(buffer, "PARAM srgb_pow = {%f, %f, %f, 1.0};\n",
- srgb_pow, srgb_pow, srgb_pow);
- shader_addline(buffer, "PARAM srgb_mul_hi = {%f, %f, %f, 1.0};\n",
- srgb_mul_high, srgb_mul_high, srgb_mul_high);
- shader_addline(buffer, "PARAM srgb_sub_hi = {%f, %f, %f, 0.0};\n",
- srgb_sub_high, srgb_sub_high, srgb_sub_high);
+ shader_addline(buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
+ srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
+ shader_addline(buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
+ srgb_sub_high, 0.0, 0.0, 0.0);
}
/* Load local constants using the program-local space,
* this avoids reloading them each time the shader is used
*/
- if(!This->baseShader.load_local_constsF) {
+ if(lconst_map) {
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
shader_addline(buffer, "PARAM C%u = program.local[%u];\n", lconst->idx,
- lconst->idx);
+ lconst_map[lconst->idx]);
}
}
* local constants do not declare the loaded constants as an array because ARB compilers usually
* do not optimize unused constants away
*/
- if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) {
+ if(This->baseShader.reg_maps.usesrelconstF) {
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */
shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
max_constantsF, max_constantsF - 1);
} else {
for(i = 0; i < max_constantsF; i++) {
- if(!shader_constant_is_local(This, i)) {
+ DWORD idx, mask;
+ idx = i >> 5;
+ mask = 1 << (i & 0x1f);
+ if(!shader_constant_is_local(This, i) && (This->baseShader.reg_maps.constf[idx] & mask)) {
shader_addline(buffer, "PARAM C%d = program.env[%d];\n",i, i);
}
}
const struct wined3d_shader_dst_param *dst, char *write_mask)
{
char *ptr = write_mask;
- char vshader = shader_is_vshader_version(ins->reg_maps->shader_version);
+ char vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
- if (vshader && dst->register_type == WINED3DSPR_ADDR)
+ if (vshader && dst->reg.type == WINED3DSPR_ADDR)
{
*ptr++ = '.';
*ptr++ = 'x';
*ptr = '\0';
}
-static void shader_arb_get_swizzle(const DWORD param, BOOL fixup, char *swizzle_str) {
+static void shader_arb_get_swizzle(const struct wined3d_shader_src_param *param, BOOL fixup, char *swizzle_str)
+{
/* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
* but addressed as "rgba". To fix this we need to swap the register's x
* and z components. */
char *ptr = swizzle_str;
/* swizzle bits fields: wwzzyyxx */
- DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+ DWORD swizzle = param->swizzle;
DWORD swizzle_x = swizzle & 0x03;
DWORD swizzle_y = (swizzle >> 2) & 0x03;
DWORD swizzle_z = (swizzle >> 4) & 0x03;
/* If the swizzle is the default swizzle (ie, "xyzw"), we don't need to
* generate a swizzle string. Unless we need to our own swizzling. */
- if ((WINED3DSP_NOSWIZZLE >> WINED3DSP_SWIZZLE_SHIFT) != swizzle || fixup) {
+ if (swizzle != WINED3DSP_NOSWIZZLE || fixup)
+ {
*ptr++ = '.';
if (swizzle_x == swizzle_y && swizzle_x == swizzle_z && swizzle_x == swizzle_w) {
*ptr++ = swizzle_chars[swizzle_x];
/* oPos, oFog and oPts in D3D */
static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"};
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
- DWORD shader_version = This->baseShader.reg_maps.shader_version;
- BOOL pshader = shader_is_pshader_version(shader_version);
+ BOOL pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
*is_color = FALSE;
}
else
{
- if (This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF))
+ if (This->baseShader.reg_maps.usesrelconstF)
sprintf(register_name, "C[%u]", register_idx);
else
sprintf(register_name, "C%u", register_idx);
}
}
-static void shader_arb_add_src_param(const struct wined3d_shader_instruction *ins,
- DWORD param, char *str)
-{
- char register_name[255];
- char swizzle[6];
- BOOL is_color;
-
- if ((param & WINED3DSP_SRCMOD_MASK) == WINED3DSPSM_NEG) strcat(str, " -");
- else strcat(str, " ");
-
- shader_arb_get_register_name(ins->shader, shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK,
- param & WINED3DSHADER_ADDRMODE_RELATIVE, register_name, &is_color);
- strcat(str, register_name);
-
- shader_arb_get_swizzle(param, is_color, swizzle);
- strcat(str, swizzle);
-}
-
-static void shader_arb_add_dst_param(const struct wined3d_shader_instruction *ins,
+static void shader_arb_get_dst_param(const struct wined3d_shader_instruction *ins,
const struct wined3d_shader_dst_param *wined3d_dst, char *str)
{
char register_name[255];
char write_mask[6];
BOOL is_color;
- strcat(str, " ");
-
- shader_arb_get_register_name(ins->shader, wined3d_dst->register_type,
- wined3d_dst->register_idx, wined3d_dst->has_rel_addr, register_name, &is_color);
- strcat(str, register_name);
+ shader_arb_get_register_name(ins->ctx->shader, wined3d_dst->reg.type,
+ wined3d_dst->reg.idx, !!wined3d_dst->reg.rel_addr, register_name, &is_color);
+ strcpy(str, register_name);
shader_arb_get_write_mask(ins, wined3d_dst, write_mask);
strcat(str, write_mask);
static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
const char *dst_str, const char *coord_reg, BOOL projected, BOOL bias)
{
- SHADER_BUFFER *buffer = ins->buffer;
- DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
const char *tex_type;
- IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader;
+ IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
switch(sampler_type) {
} else {
tex_type = "2D";
}
- if(shader_is_pshader_version(ins->reg_maps->shader_version)) {
+ if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
+ {
const IWineD3DPixelShaderImpl* const ps = (const IWineD3DPixelShaderImpl*)This;
if(ps->cur_args->np2_fixup & (1 << sampler_idx)) {
FIXME("NP2 texcoord fixup is currently not implemented in ARB mode (use GLSL instead).\n");
shader_addline(buffer, "TEX %s, %s, texture[%u], %s;\n", dst_str, coord_reg, sampler_idx, tex_type);
}
- if (shader_is_pshader_version(ins->reg_maps->shader_version))
+ if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
{
- IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
"one", "coefmul.x", ps->cur_args->color_fixup[sampler_idx]);
}
}
-static void pshader_gen_input_modifier_line (
- IWineD3DBaseShader *iface,
- SHADER_BUFFER* buffer,
- const DWORD instr,
- int tmpreg,
- char *outregstr) {
-
+static void shader_arb_get_src_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_src_param *src, unsigned int tmpreg, char *outregstr)
+{
/* Generate a line that does the input modifier computation and return the input register to use */
BOOL is_color = FALSE;
char regstr[256];
char swzstr[20];
int insert_line;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
/* Assume a new line will be added */
insert_line = 1;
/* Get register name */
- shader_arb_get_register_name(iface, shader_get_regtype(instr), instr & WINED3DSP_REGNUM_MASK,
- instr & WINED3DSHADER_ADDRMODE_RELATIVE, regstr, &is_color);
- shader_arb_get_swizzle(instr, is_color, swzstr);
+ shader_arb_get_register_name(ins->ctx->shader, src->reg.type,
+ src->reg.idx, !!src->reg.rel_addr, regstr, &is_color);
+ shader_arb_get_swizzle(src, is_color, swzstr);
- switch (instr & WINED3DSP_SRCMOD_MASK) {
+ switch (src->modifiers)
+ {
case WINED3DSPSM_NONE:
sprintf(outregstr, "%s%s", regstr, swzstr);
insert_line = 0;
sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr);
}
-static inline void pshader_gen_output_modifier_line(SHADER_BUFFER *buffer, int saturate, const char *write_mask,
- int shift, const char *regstr)
-{
- /* Generate a line that does the output modifier computation */
- shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "",
- regstr, write_mask, regstr, shift_tab[shift]);
-}
-
static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_name[50];
char src_name[2][50];
char dst_wmask[20];
- DWORD sampler_code = dst->register_idx;
+ DWORD sampler_code = dst->reg.idx;
BOOL has_bumpmat = FALSE;
BOOL is_color;
int i;
}
}
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
shader_arb_get_write_mask(ins, dst, dst_wmask);
strcat(dst_name, dst_wmask);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
if(has_bumpmat) {
/* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_wmask[20];
char dst_name[50];
char src_name[3][50];
BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
- DWORD shift = dst->shift;
BOOL is_color;
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
/* FIXME: support output modifiers */
/* Handle output register */
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
shader_arb_get_write_mask(ins, dst, dst_wmask);
/* Generate input register names (with modifiers) */
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[2], 2, src_name[2]);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
/* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
- if (ins->reg_maps->shader_version <= WINED3DPS_VERSION(1, 3) && ins->coissue)
+ if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue)
{
shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
} else {
shader_addline(buffer, "CMP%s %s%s, TMP, %s, %s;\n",
sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1], src_name[2]);
}
- if (shift != 0)
- pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
}
static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_wmask[20];
char dst_name[50];
char src_name[3][50];
- DWORD shift = dst->shift;
BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
BOOL is_color;
/* FIXME: support output modifiers */
/* Handle output register */
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
shader_arb_get_write_mask(ins, dst, dst_wmask);
/* Generate input register names (with modifiers) */
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[2], 2, src_name[2]);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
shader_addline(buffer, "CMP%s %s%s, %s, %s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
src_name[0], src_name[2], src_name[1]);
-
- if (shift != 0)
- pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
}
/** Process the WINED3DSIO_DP2ADD instruction in ARB.
static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_wmask[20];
char dst_name[50];
char src_name[3][50];
- DWORD shift = dst->shift;
BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
BOOL is_color;
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
shader_arb_get_write_mask(ins, dst, dst_wmask);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[2], 2, src_name[2]);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
/* Emulate a DP2 with a DP3 and 0.0 */
shader_addline(buffer, "MOV TMP, %s;\n", src_name[0]);
shader_addline(buffer, "MOV TMP.z, 0.0;\n");
shader_addline(buffer, "DP3 TMP2, TMP, %s;\n", src_name[1]);
shader_addline(buffer, "ADD%s %s%s, TMP2, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[2]);
-
- if (shift != 0)
- pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
}
/* Map the opcode 1-to-1 to the GL code */
static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
- const DWORD *src = ins->src;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
const char *instruction;
- char arguments[256];
+ char arguments[256], dst_str[50];
unsigned int i;
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ const char *modifier;
switch (ins->handler_idx)
{
case WINED3DSIH_MIN: instruction = "MIN"; break;
case WINED3DSIH_MOV: instruction = "MOV"; break;
case WINED3DSIH_MUL: instruction = "MUL"; break;
- case WINED3DSIH_NOP: instruction = "NOP"; break;
case WINED3DSIH_POW: instruction = "POW"; break;
case WINED3DSIH_SGE: instruction = "SGE"; break;
case WINED3DSIH_SLT: instruction = "SLT"; break;
break;
}
- if (shader_is_pshader_version(ins->reg_maps->shader_version))
- {
- /* Output token related */
- const struct wined3d_shader_dst_param *dst;
- char output_rname[256];
- char output_wmask[20];
- char operands[4][100];
- BOOL saturate = FALSE;
- BOOL centroid = FALSE;
- BOOL partialprecision = FALSE;
- const char *modifier;
- BOOL is_color;
- DWORD shift;
-
- if (!(ins->dst_count + ins->src_count))
- {
- ERR("Opcode \"%#x\" has no parameters\n", ins->handler_idx);
- return;
- }
- dst = &ins->dst[0];
-
- /* Process modifiers */
- if (dst->modifiers)
- {
- DWORD mask = dst->modifiers;
-
- saturate = mask & WINED3DSPDM_SATURATE;
- centroid = mask & WINED3DSPDM_MSAMPCENTROID;
- partialprecision = mask & WINED3DSPDM_PARTIALPRECISION;
- mask &= ~(WINED3DSPDM_MSAMPCENTROID | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_SATURATE);
- if (mask)
- FIXME("Unrecognized modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT);
-
- if (centroid)
- FIXME("Unhandled modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT);
- }
- shift = dst->shift;
- modifier = (saturate && !shift) ? "_SAT" : "";
-
- /* Generate input register names (with modifiers) */
- for (i = 0; i < ins->src_count; ++i)
- {
- pshader_gen_input_modifier_line(ins->shader, buffer, src[i], i, operands[i + 1]);
- }
-
- /* Handle output register */
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, output_rname, &is_color);
- strcpy(operands[0], output_rname);
- shader_arb_get_write_mask(ins, dst, output_wmask);
- strcat(operands[0], output_wmask);
+ /* All instructions handled by this function have a destination parameter */
+ if(dst->modifiers & WINED3DSPDM_SATURATE) modifier = "_SAT";
+ else modifier = "";
- arguments[0] = '\0';
- strcat(arguments, operands[0]);
- for (i = 0; i < ins->src_count; ++i)
- {
- strcat(arguments, ", ");
- strcat(arguments, operands[i + 1]);
- }
- shader_addline(buffer, "%s%s %s;\n", instruction, modifier, arguments);
-
- /* A shift requires another line. */
- if (shift) pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname);
- } else {
- /* Note that shader_arb_add_*_param() adds spaces. */
-
- arguments[0] = '\0';
- if (ins->dst_count)
- {
- shader_arb_add_dst_param(ins, &ins->dst[0], arguments);
- for (i = 0; i < ins->src_count; ++i)
- {
- strcat(arguments, ",");
- shader_arb_add_src_param(ins, src[i], arguments);
- }
- }
- shader_addline(buffer, "%s%s;\n", instruction, arguments);
+ /* Note that shader_arb_add_dst_param() adds spaces. */
+ arguments[0] = '\0';
+ shader_arb_get_dst_param(ins, dst, dst_str);
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ char operand[100];
+ strcat(arguments, ", ");
+ shader_arb_get_src_param(ins, &ins->src[i], i, operand);
+ strcat(arguments, operand);
}
+ shader_addline(buffer, "%s%s %s%s;\n", instruction, modifier, dst_str, arguments);
+}
+
+static void shader_hw_nop(const struct wined3d_shader_instruction *ins)
+{
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ shader_addline(buffer, "NOP;\n");
}
static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
{
- IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
+ IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
- if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1
- && !shader_is_pshader_version(ins->reg_maps->shader_version)
- && ins->dst[0].register_type == WINED3DSPR_ADDR)
+ if ((ins->ctx->reg_maps->shader_version.major == 1
+ && !shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)
+ && ins->dst[0].reg.type == WINED3DSPR_ADDR)
|| ins->handler_idx == WINED3DSIH_MOVA)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char src0_param[256];
if (ins->handler_idx == WINED3DSIH_MOVA)
src0_param[0] = '\0';
if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
{
- shader_arb_add_src_param(ins, ins->src[0], src0_param);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param);
shader_addline(buffer, "ARL A0.x, TMP.x;\n");
}
{
/* Apple's ARB_vertex_program implementation does not accept an ARL source argument
* with more than one component. Thus replicate the first source argument over all
- * 4 components. For example, .xyzw -> .x (or better: .xxxx), .zwxy -> .z, etc)
- */
- DWORD parm = ins->src[0] & ~(WINED3DVS_SWIZZLE_MASK);
- if((ins->src[0] & WINED3DVS_X_W) == WINED3DVS_X_W)
- parm |= WINED3DVS_X_W | WINED3DVS_Y_W | WINED3DVS_Z_W | WINED3DVS_W_W;
- else if((ins->src[0] & WINED3DVS_X_Z) == WINED3DVS_X_Z)
- parm |= WINED3DVS_X_Z | WINED3DVS_Y_Z | WINED3DVS_Z_Z | WINED3DVS_W_Z;
- else if((ins->src[0] & WINED3DVS_X_Y) == WINED3DVS_X_Y)
- parm |= WINED3DVS_X_Y | WINED3DVS_Y_Y | WINED3DVS_Z_Y | WINED3DVS_W_Y;
- else if((ins->src[0] & WINED3DVS_X_X) == WINED3DVS_X_X)
- parm |= WINED3DVS_X_X | WINED3DVS_Y_X | WINED3DVS_Z_X | WINED3DVS_W_X;
- shader_arb_add_src_param(ins, parm, src0_param);
+ * 4 components. For example, .xyzw -> .x (or better: .xxxx), .zwxy -> .z, etc) */
+ struct wined3d_shader_src_param tmp_src = ins->src[0];
+ tmp_src.swizzle = (tmp_src.swizzle & 0x3) * 0x55;
+ shader_arb_get_src_param(ins, &tmp_src, 0, src0_param);
shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
}
}
static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- DWORD shader_version = ins->reg_maps->shader_version;
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char reg_dest[40];
- BOOL is_color;
/* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
* but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit)
*/
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, reg_dest, &is_color);
+ shader_arb_get_dst_param(ins, dst, reg_dest);
- if (shader_version >= WINED3DPS_VERSION(2,0))
+ if (ins->ctx->reg_maps->shader_version.major >= 2)
{
/* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
shader_addline(buffer, "KIL %s;\n", reg_dest);
/* ARB fp doesn't like swizzles on the parameter of the KIL instruction. To mask the 4th component,
* copy the register into our general purpose TMP variable, overwrite .w and pass TMP to KIL
*/
- shader_addline(buffer, "MOV TMP, %s;\n", reg_dest);
- shader_addline(buffer, "MOV TMP.w, one.w;\n");
+ shader_addline(buffer, "SWZ TMP, %s, x, y, z, 1;\n", reg_dest);
shader_addline(buffer, "KIL TMP;\n");
}
}
static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
BOOL is_color;
-
- const DWORD *src = ins->src;
- SHADER_BUFFER* buffer = ins->buffer;
- DWORD shader_version = ins->reg_maps->shader_version;
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
BOOL projected = FALSE, bias = FALSE;
char reg_dest[40];
DWORD reg_sampler_code;
/* All versions have a destination register */
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, reg_dest, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, reg_dest, &is_color);
/* 1.0-1.3: Use destination register as coordinate source.
1.4+: Use provided coordinate source register. */
- if (shader_version < WINED3DPS_VERSION(1,4))
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
strcpy(reg_coord, reg_dest);
else
- pshader_gen_input_modifier_line(ins->shader, buffer, src[0], 0, reg_coord);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, reg_coord);
/* 1.0-1.4: Use destination register number as texture code.
2.0+: Use provided sampler number as texure code. */
- if (shader_version < WINED3DPS_VERSION(2,0))
- reg_sampler_code = dst->register_idx;
+ if (shader_version < WINED3D_SHADER_VERSION(2,0))
+ reg_sampler_code = dst->reg.idx;
else
- reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK;
+ reg_sampler_code = ins->src[1].reg.idx;
/* projection flag:
* 1.1, 1.2, 1.3: Use WINED3DTSS_TEXTURETRANSFORMFLAGS
* 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0]
* 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode
*/
- if (shader_version < WINED3DPS_VERSION(1,4))
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
{
DWORD flags = 0;
if(reg_sampler_code < MAX_TEXTURES) {
projected = TRUE;
}
}
- else if (shader_version < WINED3DPS_VERSION(2,0))
+ else if (shader_version < WINED3D_SHADER_VERSION(2,0))
{
- DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK;
+ DWORD src_mod = ins->src[0].modifiers;
if (src_mod == WINED3DSPSM_DZ) {
projected = TRUE;
} else if(src_mod == WINED3DSPSM_DW) {
static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
char tmp[20];
shader_arb_get_write_mask(ins, dst, tmp);
- if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
+ if (shader_version != WINED3D_SHADER_VERSION(1,4))
{
- DWORD reg = dst->register_idx;
+ DWORD reg = dst->reg.idx;
shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
} else {
char reg_src[40];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, reg_src);
- shader_addline(buffer, "MOV R%u%s, %s;\n", dst->register_idx, tmp, reg_src);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src);
+ shader_addline(buffer, "MOV R%u%s, %s;\n", dst->reg.idx, tmp, reg_src);
}
}
static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
DWORD flags;
- DWORD reg1 = ins->dst[0].register_idx;
+ DWORD reg1 = ins->dst[0].reg.idx;
char dst_str[8];
char src_str[50];
sprintf(dst_str, "T%u", reg1);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
shader_addline(buffer, "MOV TMP.x, %s.w;\n", src_str);
shader_addline(buffer, "MOV TMP.y, %s.x;\n", src_str);
flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
- DWORD reg1 = ins->dst[0].register_idx;
+ DWORD reg1 = ins->dst[0].reg.idx;
char dst_str[8];
char src_str[50];
sprintf(dst_str, "T%u", reg1);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
shader_addline(buffer, "MOV TMP.x, %s.y;\n", src_str);
shader_addline(buffer, "MOV TMP.y, %s.z;\n", src_str);
shader_hw_sample(ins, reg1, dst_str, "TMP", FALSE, FALSE);
static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
- DWORD reg1 = ins->dst[0].register_idx;
+ DWORD reg1 = ins->dst[0].reg.idx;
char dst_str[8];
char src_str[50];
sprintf(dst_str, "T%u", reg1);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
shader_hw_sample(ins, reg1, dst_str, src_str, FALSE, FALSE);
}
static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
BOOL has_bumpmat = FALSE;
BOOL has_luminance = FALSE;
BOOL is_color;
int i;
- DWORD src = ins->src[0] & WINED3DSP_REGNUM_MASK;
- SHADER_BUFFER* buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char reg_coord[40];
DWORD reg_dest_code;
/* All versions have a destination register */
- reg_dest_code = dst->register_idx;
+ reg_dest_code = dst->reg.idx;
/* Can directly use the name because texbem is only valid for <= 1.3 shaders */
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, reg_coord, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, reg_coord, &is_color);
for(i = 0; i < This->numbumpenvmatconsts; i++) {
if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED
}
if(has_bumpmat) {
+ DWORD src = ins->src[0].reg.idx;
+
/* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
{
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char src0_name[50];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", reg, src0_name);
}
static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
DWORD flags;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_str[8];
char src0_name[50];
sprintf(dst_str, "T%u", reg);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", reg, src0_name);
flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
char src0_name[50];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
shader_addline(buffer, "DP3 TMP.%c, T%u, %s;\n", 'x' + current_state->current_row, reg, src0_name);
current_state->texcoord_w[current_state->current_row++] = reg;
}
static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
DWORD flags;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
char dst_str[8];
char src0_name[50];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
/* Sample the texture using the calculated coordinates */
static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
DWORD flags;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
char dst_str[8];
char src0_name[50];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
/* Construct the eye-ray vector from w coordinates */
static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
DWORD flags;
- DWORD reg = ins->dst[0].register_idx;
- DWORD reg3 = ins->src[1] & WINED3DSP_REGNUM_MASK;
+ DWORD reg = ins->dst[0].reg.idx;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_str[8];
char src0_name[50];
+ char src1_name[50];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 1, src1_name);
shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
/* Calculate reflection vector.
*
* Which normalizes the normal vector
*/
- shader_addline(buffer, "DP3 TMP.w, TMP, C[%u];\n", reg3);
+ shader_addline(buffer, "DP3 TMP.w, TMP, %s;\n", src1_name);
shader_addline(buffer, "DP3 TMP2.w, TMP, TMP;\n");
shader_addline(buffer, "RCP TMP2.w, TMP2.w;\n");
shader_addline(buffer, "MUL TMP.w, TMP.w, TMP2.w;\n");
shader_addline(buffer, "MUL TMP, TMP.w, TMP;\n");
- shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -C[%u];\n", reg3);
+ shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -%s;\n", src1_name);
/* Sample the texture using the calculated coordinates */
sprintf(dst_str, "T%u", reg);
static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_name[50];
BOOL is_color;
* parameter. According to the msdn, this must be register r5, but let's keep it more flexible
* here
*/
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
/* According to the msdn, the source register(must be r5) is unusable after
* the texdepth instruction, so we're free to modify it
* then perform a 1D texture lookup from stage dstregnum, place into dst. */
static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
- DWORD sampler_idx = ins->dst[0].register_idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ DWORD sampler_idx = ins->dst[0].reg.idx;
char src0[50];
char dst_str[8];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
shader_addline(buffer, "MOV TMP, 0.0;\n");
shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", sampler_idx, src0);
char src0[50];
char dst_str[50];
char dst_mask[6];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
BOOL is_color;
/* Handle output register */
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_str, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color);
shader_arb_get_write_mask(ins, dst, dst_mask);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
- shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->register_idx, src0);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+ shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->reg.idx, src0);
/* TODO: Handle output modifiers */
}
static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_str[50];
char dst_mask[6];
char src0[50];
BOOL is_color;
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_str, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color);
shader_arb_get_write_mask(ins, dst, dst_mask);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
- shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->register_idx, src0);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+ shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->reg.idx, src0);
shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask);
/* TODO: Handle output modifiers */
*/
static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
- DWORD dst_reg = ins->dst[0].register_idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ DWORD dst_reg = ins->dst[0].reg.idx;
char src0[50];
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", dst_reg, src0);
/* How to deal with the special case dst_name.g == 0? if r != 0, then
{
int i;
int nComponents = 0;
- struct wined3d_shader_dst_param tmp_dst = {0};
+ struct wined3d_shader_dst_param tmp_dst = {{0}};
+ struct wined3d_shader_src_param tmp_src[2] = {{{0}}};
struct wined3d_shader_instruction tmp_ins;
memset(&tmp_ins, 0, sizeof(tmp_ins));
/* Set constants for the temporary argument */
- tmp_ins.shader = ins->shader;
- tmp_ins.buffer = ins->buffer;
- tmp_ins.src[0] = ins->src[0];
- tmp_ins.src_addr[0] = ins->src_addr[0];
- tmp_ins.src_addr[1] = ins->src_addr[1];
- tmp_ins.reg_maps = ins->reg_maps;
+ tmp_ins.ctx = ins->ctx;
tmp_ins.dst_count = 1;
tmp_ins.dst = &tmp_dst;
tmp_ins.src_count = 2;
+ tmp_ins.src = tmp_src;
switch(ins->handler_idx)
{
}
tmp_dst = ins->dst[0];
+ tmp_src[0] = ins->src[0];
+ tmp_src[1] = ins->src[1];
for (i = 0; i < nComponents; i++) {
tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
- tmp_ins.src[1] = ins->src[1]+i;
shader_hw_map2gl(&tmp_ins);
+ ++tmp_src[1].reg.idx;
}
}
-static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
+static void shader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
- DWORD src = ins->src[0];
- DWORD swizzle = (src & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
- const char *instruction;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ const char *instruction, *sat;
- char tmpLine[256];
+ char dst[50];
+ char src[50];
switch(ins->handler_idx)
{
break;
}
- strcpy(tmpLine, instruction);
- shader_arb_add_dst_param(ins, &ins->dst[0], tmpLine); /* Destination */
- strcat(tmpLine, ",");
- shader_arb_add_src_param(ins, src, tmpLine);
- if ((WINED3DSP_NOSWIZZLE >> WINED3DSP_SWIZZLE_SHIFT) == swizzle) {
+ if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE) sat = "_SAT";
+ else sat = "";
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src);
+ if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE)
+ {
/* Dx sdk says .x is used if no swizzle is given, but our test shows that
* .w is used
*/
- strcat(tmpLine, ".w");
+ strcat(src, ".w");
}
- shader_addline(buffer, "%s;\n", tmpLine);
+ shader_addline(buffer, "%s%s %s, %s;\n", instruction, sat, dst, src);
}
static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_name[50];
char src_name[50];
char dst_wmask[20];
- DWORD shift = dst->shift;
BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
BOOL is_color;
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
shader_arb_get_write_mask(ins, dst, dst_wmask);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
shader_addline(buffer, "DP3 TMP, %s, %s;\n", src_name, src_name);
shader_addline(buffer, "RSQ TMP, TMP.x;\n");
/* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/
shader_addline(buffer, "MUL%s %s%s, %s, TMP;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
src_name);
-
- if (shift != 0)
- pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
}
static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
* can't use map2gl
*/
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
char dst_name[50];
char src_name[50];
char dst_wmask[20];
- DWORD shift = dst->shift;
BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
BOOL is_color;
- shader_arb_get_register_name(ins->shader, dst->register_type,
- dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
shader_arb_get_write_mask(ins, dst, dst_wmask);
- pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
shader_addline(buffer, "SCS%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
src_name);
-
- if (shift != 0)
- pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
-
}
static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info)
IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface;
const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info;
- if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version))
+ if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version.type))
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
UINT i;
/* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
/* Calculate the > 0.0031308 case */
- shader_addline(buffer, "POW %s.x, %s.x, srgb_pow.x;\n", tmp1, fragcolor);
- shader_addline(buffer, "POW %s.y, %s.y, srgb_pow.y;\n", tmp1, fragcolor);
- shader_addline(buffer, "POW %s.z, %s.z, srgb_pow.z;\n", tmp1, fragcolor);
- shader_addline(buffer, "MUL %s, %s, srgb_mul_hi;\n", tmp1, tmp1);
- shader_addline(buffer, "SUB %s, %s, srgb_sub_hi;\n", tmp1, tmp1);
+ shader_addline(buffer, "POW %s.x, %s.x, srgb_consts1.z;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.y, %s.y, srgb_consts1.z;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.z, %s.z, srgb_consts1.z;\n", tmp1, fragcolor);
+ shader_addline(buffer, "MUL %s, %s, srgb_consts1.w;\n", tmp1, tmp1);
+ shader_addline(buffer, "SUB %s, %s, srgb_consts2.x;\n", tmp1, tmp1);
/* Calculate the < case */
- shader_addline(buffer, "MUL %s, srgb_mul_low, %s;\n", tmp2, fragcolor);
+ shader_addline(buffer, "MUL %s, srgb_consts1.x, %s;\n", tmp2, fragcolor);
/* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
- shader_addline(buffer, "SLT %s, srgb_comparison, %s;\n", tmp3, fragcolor);
- shader_addline(buffer, "SGE %s, srgb_comparison, %s;\n", tmp4, fragcolor);
+ shader_addline(buffer, "SLT %s, srgb_consts1.y, %s;\n", tmp3, fragcolor);
+ shader_addline(buffer, "SGE %s, srgb_consts1.y, %s;\n", tmp4, fragcolor);
/* Store the components > 0.0031308 in the destination */
shader_addline(buffer, "MUL %s, %s, %s;\n", fragcolor, tmp1, tmp3);
/* Add the components that are < 0.0031308 */
/* [0.0;1.0] clamping. Not needed, this is done implicitly */
}
-static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
+static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface,
+ SHADER_BUFFER *buffer, const struct ps_compile_args *args)
+{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
- DWORD shader_version = reg_maps->shader_version;
const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
const local_constant *lconst;
GLuint retval;
const char *fragcolor;
+ DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This);
/* Create the hw ARB shader */
shader_addline(buffer, "!!ARBfp1.0\n");
- if (shader_version < WINED3DPS_VERSION(3,0)) {
+ if (reg_maps->shader_version.major < 3)
+ {
switch(args->fog) {
case FOG_OFF:
break;
shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
- if (shader_version < WINED3DPS_VERSION(2,0)) {
+ if (reg_maps->shader_version.major < 2)
+ {
fragcolor = "R0";
} else {
shader_addline(buffer, "TEMP TMP_COLOR;\n");
}
/* Base Declarations */
- shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
+ shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, lconst_map);
/* Base Shader Body */
- shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
+ shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
if(args->srgb_correction) {
arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
}
/* Load immediate constants */
- if(!This->baseShader.load_local_constsF) {
+ if(lconst_map) {
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
const float *value = (const float *)lconst->value;
- GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst->idx, value));
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value));
checkGLcall("glProgramLocalParameter4fvARB");
}
+ HeapFree(GetProcessHeap(), 0, lconst_map);
}
return retval;
}
-static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
+static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface,
+ SHADER_BUFFER *buffer, const struct vs_compile_args *args)
+{
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
const local_constant *lconst;
GLuint ret;
+ DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This);
/* Create the hw ARB shader */
shader_addline(buffer, "!!ARBvp1.0\n");
shader_addline(buffer, "TEMP TMP;\n");
/* Base Declarations */
- shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
+ shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, lconst_map);
/* We need a constant to fixup the final position */
shader_addline(buffer, "PARAM posFixup = program.env[%d];\n", ARB_SHADER_PRIVCONST_POS);
}
/* Base Shader Body */
- shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
+ shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
* or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
if(args->fog_src == VS_FOG_Z) {
shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n");
} else if (!reg_maps->fog) {
- shader_addline(buffer, "MOV result.fogcoord, 0.0;\n");
+ shader_addline(buffer, "MOV result.fogcoord, helper_const.w;\n");
}
/* Write the final position.
ret = -1;
} else {
/* Load immediate constants */
- if(!This->baseShader.load_local_constsF) {
+ if(lconst_map) {
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
const float *value = (const float *)lconst->value;
- GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value));
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst_map[lconst->idx], value));
}
}
}
+ HeapFree(GetProcessHeap(), 0, lconst_map);
+
return ret;
}
return FALSE;
}
+static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {
+ BOOL saturate;
+ DWORD shift;
+ char write_mask[20], regstr[50];
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ BOOL is_color = FALSE;
+ const struct wined3d_shader_dst_param *dst;
+
+ if (!ins->dst_count) return;
+
+ dst = &ins->dst[0];
+ shift = dst->shift;
+ if(shift == 0) return; /* Saturate alone is handled by the instructions */
+ saturate = dst->modifiers & WINED3DSPDM_SATURATE;
+
+ shader_arb_get_write_mask(ins, dst, write_mask);
+ shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+ dst->reg.idx, !!dst->reg.rel_addr, regstr, &is_color);
+
+ /* Generate a line that does the output modifier computation */
+ shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "",
+ regstr, write_mask, regstr, shift_tab[shift]);
+}
+
static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =
{
/* WINED3DSIH_ABS */ shader_hw_map2gl,
/* WINED3DSIH_MOV */ shader_hw_mov,
/* WINED3DSIH_MOVA */ shader_hw_mov,
/* WINED3DSIH_MUL */ shader_hw_map2gl,
- /* WINED3DSIH_NOP */ shader_hw_map2gl,
+ /* WINED3DSIH_NOP */ shader_hw_nop,
/* WINED3DSIH_NRM */ shader_hw_nrm,
/* WINED3DSIH_PHASE */ NULL,
/* WINED3DSIH_POW */ shader_hw_map2gl,
- /* WINED3DSIH_RCP */ vshader_hw_rsq_rcp,
+ /* WINED3DSIH_RCP */ shader_hw_rsq_rcp,
/* WINED3DSIH_REP */ NULL,
/* WINED3DSIH_RET */ NULL,
- /* WINED3DSIH_RSQ */ vshader_hw_rsq_rcp,
+ /* WINED3DSIH_RSQ */ shader_hw_rsq_rcp,
/* WINED3DSIH_SETP */ NULL,
/* WINED3DSIH_SGE */ shader_hw_map2gl,
/* WINED3DSIH_SGN */ NULL,
shader_arb_generate_vshader,
shader_arb_get_caps,
shader_arb_color_fixup_supported,
+ shader_arb_add_instruction_modifiers,
};
/* ARB_fragment_program fixed function pipeline replacement definitions */
shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE);
if(settings->sRGB_write) {
- shader_addline(&buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
- srgb_mul_low, srgb_mul_low, srgb_mul_low);
- shader_addline(&buffer, "PARAM srgb_comparison = {%f, %f, %f, %f};\n",
- srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
- shader_addline(&buffer, "PARAM srgb_pow = {%f, %f, %f, 1.0};\n",
- srgb_pow, srgb_pow, srgb_pow);
- shader_addline(&buffer, "PARAM srgb_mul_hi = {%f, %f, %f, 1.0};\n",
- srgb_mul_high, srgb_mul_high, srgb_mul_high);
- shader_addline(&buffer, "PARAM srgb_sub_hi = {%f, %f, %f, 0.0};\n",
- srgb_sub_high, srgb_sub_high, srgb_sub_high);
+ shader_addline(&buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
+ srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
+ shader_addline(&buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
+ srgb_sub_high, 0.0, 0.0, 0.0);
}
/* Generate texture sampling instructions) */
* Copyright 2005 Oliver Stieber
* Copyright 2006 Ivan Gyurdiev
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
-static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version);
+static const char *shader_opcode_names[] =
+{
+ /* WINED3DSIH_ABS */ "abs",
+ /* WINED3DSIH_ADD */ "add",
+ /* WINED3DSIH_BEM */ "bem",
+ /* WINED3DSIH_BREAK */ "break",
+ /* WINED3DSIH_BREAKC */ "breakc",
+ /* WINED3DSIH_BREAKP */ "breakp",
+ /* WINED3DSIH_CALL */ "call",
+ /* WINED3DSIH_CALLNZ */ "callnz",
+ /* WINED3DSIH_CMP */ "cmp",
+ /* WINED3DSIH_CND */ "cnd",
+ /* WINED3DSIH_CRS */ "crs",
+ /* WINED3DSIH_DCL */ "dcl",
+ /* WINED3DSIH_DEF */ "def",
+ /* WINED3DSIH_DEFB */ "defb",
+ /* WINED3DSIH_DEFI */ "defi",
+ /* WINED3DSIH_DP2ADD */ "dp2add",
+ /* WINED3DSIH_DP3 */ "dp3",
+ /* WINED3DSIH_DP4 */ "dp4",
+ /* WINED3DSIH_DST */ "dst",
+ /* WINED3DSIH_DSX */ "dsx",
+ /* WINED3DSIH_DSY */ "dsy",
+ /* WINED3DSIH_ELSE */ "else",
+ /* WINED3DSIH_ENDIF */ "endif",
+ /* WINED3DSIH_ENDLOOP */ "endloop",
+ /* WINED3DSIH_ENDREP */ "endrep",
+ /* WINED3DSIH_EXP */ "exp",
+ /* WINED3DSIH_EXPP */ "expp",
+ /* WINED3DSIH_FRC */ "frc",
+ /* WINED3DSIH_IF */ "if",
+ /* WINED3DSIH_IFC */ "ifc",
+ /* WINED3DSIH_LABEL */ "label",
+ /* WINED3DSIH_LIT */ "lit",
+ /* WINED3DSIH_LOG */ "log",
+ /* WINED3DSIH_LOGP */ "logp",
+ /* WINED3DSIH_LOOP */ "loop",
+ /* WINED3DSIH_LRP */ "lrp",
+ /* WINED3DSIH_M3x2 */ "m3x2",
+ /* WINED3DSIH_M3x3 */ "m3x3",
+ /* WINED3DSIH_M3x4 */ "m3x4",
+ /* WINED3DSIH_M4x3 */ "m4x3",
+ /* WINED3DSIH_M4x4 */ "m4x4",
+ /* WINED3DSIH_MAD */ "mad",
+ /* WINED3DSIH_MAX */ "max",
+ /* WINED3DSIH_MIN */ "min",
+ /* WINED3DSIH_MOV */ "mov",
+ /* WINED3DSIH_MOVA */ "mova",
+ /* WINED3DSIH_MUL */ "mul",
+ /* WINED3DSIH_NOP */ "nop",
+ /* WINED3DSIH_NRM */ "nrm",
+ /* WINED3DSIH_PHASE */ "phase",
+ /* WINED3DSIH_POW */ "pow",
+ /* WINED3DSIH_RCP */ "rcp",
+ /* WINED3DSIH_REP */ "rep",
+ /* WINED3DSIH_RET */ "ret",
+ /* WINED3DSIH_RSQ */ "rsq",
+ /* WINED3DSIH_SETP */ "setp",
+ /* WINED3DSIH_SGE */ "sge",
+ /* WINED3DSIH_SGN */ "sgn",
+ /* WINED3DSIH_SINCOS */ "sincos",
+ /* WINED3DSIH_SLT */ "slt",
+ /* WINED3DSIH_SUB */ "sub",
+ /* WINED3DSIH_TEX */ "texld",
+ /* WINED3DSIH_TEXBEM */ "texbem",
+ /* WINED3DSIH_TEXBEML */ "texbeml",
+ /* WINED3DSIH_TEXCOORD */ "texcrd",
+ /* WINED3DSIH_TEXDEPTH */ "texdepth",
+ /* WINED3DSIH_TEXDP3 */ "texdp3",
+ /* WINED3DSIH_TEXDP3TEX */ "texdp3tex",
+ /* WINED3DSIH_TEXKILL */ "texkill",
+ /* WINED3DSIH_TEXLDD */ "texldd",
+ /* WINED3DSIH_TEXLDL */ "texldl",
+ /* WINED3DSIH_TEXM3x2DEPTH */ "texm3x2depth",
+ /* WINED3DSIH_TEXM3x2PAD */ "texm3x2pad",
+ /* WINED3DSIH_TEXM3x2TEX */ "texm3x2tex",
+ /* WINED3DSIH_TEXM3x3 */ "texm3x3",
+ /* WINED3DSIH_TEXM3x3DIFF */ "texm3x3diff",
+ /* WINED3DSIH_TEXM3x3PAD */ "texm3x3pad",
+ /* WINED3DSIH_TEXM3x3SPEC */ "texm3x3spec",
+ /* WINED3DSIH_TEXM3x3TEX */ "texm3x3tex",
+ /* WINED3DSIH_TEXM3x3VSPEC */ "texm3x3vspec",
+ /* WINED3DSIH_TEXREG2AR */ "texreg2ar",
+ /* WINED3DSIH_TEXREG2GB */ "texreg2gb",
+ /* WINED3DSIH_TEXREG2RGB */ "texreg2rgb",
+};
+
+const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token)
+{
+ switch (version_token >> 16)
+ {
+ case WINED3D_SM1_VS:
+ case WINED3D_SM1_PS:
+ return &sm1_shader_frontend;
+
+ case WINED3D_SM4_PS:
+ case WINED3D_SM4_VS:
+ case WINED3D_SM4_GS:
+ return &sm4_shader_frontend;
+
+ default:
+ FIXME("Unrecognised version token %#x\n", version_token);
+ return NULL;
+ }
+}
static inline BOOL shader_is_version_token(DWORD token) {
return shader_is_pshader_version(token) ||
return ret;
}
-void shader_init(struct IWineD3DBaseShaderClass *shader,
- IWineD3DDevice *device, const SHADER_OPCODE *instruction_table)
+void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device)
{
shader->ref = 1;
shader->device = device;
- shader->shader_ins = instruction_table;
list_init(&shader->linked_programs);
}
-const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *opcode_table, DWORD shader_version, DWORD code)
+/* Convert floating point offset relative
+ * to a register file to an absolute offset for float constants */
+static unsigned int shader_get_float_offset(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx)
{
- DWORD i = 0;
-
- /** TODO: use dichotomic search */
- while (opcode_table[i].name)
+ switch (register_type)
{
- if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode
- && shader_version >= opcode_table[i].min_version
- && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version))
- {
- return &opcode_table[i];
- }
- ++i;
+ case WINED3DSPR_CONST: return register_idx;
+ case WINED3DSPR_CONST2: return 2048 + register_idx;
+ case WINED3DSPR_CONST3: return 4096 + register_idx;
+ case WINED3DSPR_CONST4: return 6144 + register_idx;
+ default:
+ FIXME("Unsupported register type: %d\n", register_type);
+ return register_idx;
}
-
- FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n",
- code, code, code & WINED3DSI_OPCODE_MASK, shader_version);
-
- return NULL;
}
-/* Read a parameter opcode from the input stream,
- * and possibly a relative addressing token.
- * Return the number of tokens read */
-static int shader_get_param(const DWORD *pToken, DWORD shader_version, DWORD *param, DWORD *addr_token)
-{
- /* PS >= 3.0 have relative addressing (with token)
- * VS >= 2.0 have relative addressing (with token)
- * VS >= 1.0 < 2.0 have relative addressing (without token)
- * The version check below should work in general */
+static void shader_delete_constant_list(struct list* clist) {
- char rel_token = WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2 &&
- ((*pToken & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE);
+ struct list *ptr;
+ struct local_constant* constant;
- *param = *pToken;
- *addr_token = rel_token? *(pToken + 1): 0;
- return rel_token? 2:1;
+ ptr = list_head(clist);
+ while (ptr) {
+ constant = LIST_ENTRY(ptr, struct local_constant, entry);
+ ptr = list_next(clist, ptr);
+ HeapFree(GetProcessHeap(), 0, constant);
+ }
+ list_init(clist);
}
-/* Return the number of parameters to skip for an opcode */
-static inline int shader_skip_opcode(const SHADER_OPCODE *curOpcode, DWORD opcode_token, DWORD shader_version)
+static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
{
- /* Shaders >= 2.0 may contain address tokens, but fortunately they
- * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */
- return (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
- ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : curOpcode->num_params;
+ DWORD idx, shift;
+ idx = bit >> 5;
+ shift = bit & 0x1f;
+ bitmap[idx] |= (1 << shift);
}
-/* Read the parameters of an unrecognized opcode from the input stream
- * Return the number of tokens read.
- *
- * Note: This function assumes source or destination token format.
- * It will not work with specially-formatted tokens like DEF or DCL,
- * but hopefully those would be recognized */
-static int shader_skip_unrecognized(const DWORD *pToken, DWORD shader_version)
+static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps,
+ DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader)
{
- int tokens_read = 0;
- int i = 0;
+ switch (register_type)
+ {
+ case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
+ if (pshader) reg_maps->texcoord[register_idx] = 1;
+ else reg_maps->address[register_idx] = 1;
+ break;
+
+ case WINED3DSPR_TEMP:
+ reg_maps->temporary[register_idx] = 1;
+ break;
+
+ case WINED3DSPR_INPUT:
+ if (!pshader) reg_maps->attributes[register_idx] = 1;
+ else
+ {
+ if (has_rel_addr)
+ {
+ /* If relative addressing is used, we must assume that all registers
+ * are used. Even if it is a construct like v3[aL], we can't assume
+ * that v0, v1 and v2 aren't read because aL can be negative */
+ unsigned int i;
+ for (i = 0; i < MAX_REG_INPUT; ++i)
+ {
+ ((IWineD3DPixelShaderImpl *)This)->input_reg_used[i] = TRUE;
+ }
+ }
+ else
+ {
+ ((IWineD3DPixelShaderImpl *)This)->input_reg_used[register_idx] = TRUE;
+ }
+ }
+ break;
+
+ case WINED3DSPR_RASTOUT:
+ if (register_idx == 1) reg_maps->fog = 1;
+ break;
+
+ case WINED3DSPR_MISCTYPE:
+ if (pshader && register_idx == 0) reg_maps->vpos = 1;
+ break;
+
+ case WINED3DSPR_CONST:
+ if (has_rel_addr)
+ {
+ if (!pshader)
+ {
+ if (register_idx <= ((IWineD3DVertexShaderImpl *)This)->min_rel_offset)
+ ((IWineD3DVertexShaderImpl *)This)->min_rel_offset = register_idx;
+ else if (register_idx >= ((IWineD3DVertexShaderImpl *)This)->max_rel_offset)
+ ((IWineD3DVertexShaderImpl *)This)->max_rel_offset = register_idx;
+ }
+ reg_maps->usesrelconstF = TRUE;
+ }
+ else
+ {
+ set_bitmap_bit(reg_maps->constf, register_idx);
+ }
+ break;
- /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
- while (*pToken & 0x80000000) {
+ case WINED3DSPR_CONSTINT:
+ reg_maps->integer_constants |= (1 << register_idx);
+ break;
- DWORD param, addr_token;
- tokens_read += shader_get_param(pToken, shader_version, ¶m, &addr_token);
- pToken += tokens_read;
+ case WINED3DSPR_CONSTBOOL:
+ reg_maps->boolean_constants |= (1 << register_idx);
+ break;
- FIXME("Unrecognized opcode param: token=0x%08x "
- "addr_token=0x%08x name=", param, addr_token);
- shader_dump_param(param, addr_token, i, shader_version);
- FIXME("\n");
- ++i;
+ default:
+ TRACE("Not recording register of type %#x and idx %u\n", register_type, register_idx);
+ break;
}
- return tokens_read;
}
-/* Convert floating point offset relative
- * to a register file to an absolute offset for float constants */
-static unsigned int shader_get_float_offset(const DWORD reg)
+static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param)
{
- unsigned int regnum = reg & WINED3DSP_REGNUM_MASK;
- int regtype = shader_get_regtype(reg);
-
- switch (regtype) {
- case WINED3DSPR_CONST: return regnum;
- case WINED3DSPR_CONST2: return 2048 + regnum;
- case WINED3DSPR_CONST3: return 4096 + regnum;
- case WINED3DSPR_CONST4: return 6144 + regnum;
- default:
- FIXME("Unsupported register type: %d\n", regtype);
- return regnum;
- }
-}
+ switch(instr)
+ {
+ case WINED3DSIH_M4x4:
+ case WINED3DSIH_M3x4:
+ return param == 1 ? 4 : 1;
-static void shader_delete_constant_list(struct list* clist) {
+ case WINED3DSIH_M4x3:
+ case WINED3DSIH_M3x3:
+ return param == 1 ? 3 : 1;
- struct list *ptr;
- struct local_constant* constant;
+ case WINED3DSIH_M3x2:
+ return param == 1 ? 2 : 1;
- ptr = list_head(clist);
- while (ptr) {
- constant = LIST_ENTRY(ptr, struct local_constant, entry);
- ptr = list_next(clist, ptr);
- HeapFree(GetProcessHeap(), 0, constant);
+ default:
+ return 1;
}
- list_init(clist);
-}
-
-static void shader_parse_dst_param(DWORD param, DWORD addr_param, struct wined3d_shader_dst_param *dst)
-{
- dst->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
- | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
- dst->register_idx = param & WINED3DSP_REGNUM_MASK;
- dst->write_mask = param & WINED3DSP_WRITEMASK_ALL;
- dst->modifiers = param & WINED3DSP_DSTMOD_MASK;
- dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
- dst->has_rel_addr = param & WINED3DSHADER_ADDRMODE_RELATIVE;
- dst->addr_token = addr_param;
}
/* Note that this does not count the loop register
* as an address register. */
-HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
- struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out,
- const DWORD *byte_code)
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
+ struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
+ struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size)
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
- const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
- DWORD shader_version;
+ void *fe_data = This->baseShader.frontend_data;
+ struct wined3d_shader_version shader_version;
unsigned int cur_loop_depth = 0, max_loop_depth = 0;
const DWORD* pToken = byte_code;
char pshader;
/* There are some minor differences between pixel and vertex shaders */
- memset(reg_maps->bumpmat, 0, sizeof(reg_maps->bumpmat));
- memset(reg_maps->luminanceparams, 0, sizeof(reg_maps->luminanceparams));
+ memset(reg_maps, 0, sizeof(*reg_maps));
/* get_registers_used is called on every compile on some 1.x shaders, which can result
* in stacking up a collection of local constants. Delete the old constants if existing
shader_delete_constant_list(&This->baseShader.constantsB);
shader_delete_constant_list(&This->baseShader.constantsI);
- /* The version token is supposed to be the first token */
- if (!shader_is_version_token(*pToken))
- {
- FIXME("First token is not a version token, invalid shader.\n");
- return WINED3DERR_INVALIDCALL;
+ fe->shader_read_header(fe_data, &pToken, &shader_version);
+ reg_maps->shader_version = shader_version;
+ pshader = shader_is_pshader_version(shader_version.type);
+
+ reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
+ if(!reg_maps->constf) {
+ ERR("Out of memory\n");
+ return E_OUTOFMEMORY;
}
- reg_maps->shader_version = shader_version = *pToken++;
- pshader = shader_is_pshader_version(shader_version);
- while (WINED3DVS_END() != *pToken) {
- CONST SHADER_OPCODE* curOpcode;
- DWORD opcode_token;
+ while (!fe->shader_is_end(fe_data, &pToken))
+ {
+ struct wined3d_shader_instruction ins;
+ const char *comment;
+ UINT param_size;
/* Skip comments */
- if (shader_is_comment(*pToken))
- {
- DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
- ++pToken;
- pToken += comment_len;
- continue;
- }
+ fe->shader_read_comment(&pToken, &comment);
+ if (comment) continue;
/* Fetch opcode */
- opcode_token = *pToken++;
- curOpcode = shader_get_opcode(shader_ins, shader_version, opcode_token);
+ fe->shader_read_opcode(fe_data, &pToken, &ins, ¶m_size);
/* Unhandled opcode, and its parameters */
- if (NULL == curOpcode) {
- while (*pToken & 0x80000000)
- ++pToken;
+ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
+ {
+ TRACE("Skipping unrecognized instruction.\n");
+ pToken += param_size;
+ continue;
+ }
/* Handle declarations */
- } else if (WINED3DSIO_DCL == curOpcode->opcode) {
-
- DWORD usage = *pToken++;
- DWORD param = *pToken++;
- DWORD regtype = shader_get_regtype(param);
- unsigned int regnum = param & WINED3DSP_REGNUM_MASK;
-
- /* Vshader: mark attributes used
- Pshader: mark 3.0 input registers used, save token */
- if (WINED3DSPR_INPUT == regtype) {
-
- if (!pshader)
- reg_maps->attributes[regnum] = 1;
- else
- reg_maps->packed_input[regnum] = 1;
-
- semantics_in[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
- semantics_in[regnum].usage_idx =
- (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
- shader_parse_dst_param(param, 0, &semantics_in[regnum].reg);
-
- /* Vshader: mark 3.0 output registers used, save token */
- } else if (WINED3DSPR_OUTPUT == regtype) {
- reg_maps->packed_output[regnum] = 1;
- semantics_out[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
- semantics_out[regnum].usage_idx =
- (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
- shader_parse_dst_param(param, 0, &semantics_out[regnum].reg);
+ if (ins.handler_idx == WINED3DSIH_DCL)
+ {
+ struct wined3d_shader_semantic semantic;
- if (usage & (WINED3DDECLUSAGE_FOG << WINED3DSP_DCL_USAGE_SHIFT))
- reg_maps->fog = 1;
+ fe->shader_read_semantic(&pToken, &semantic);
- /* Save sampler usage token */
- } else if (WINED3DSPR_SAMPLER == regtype)
- reg_maps->samplers[regnum] = usage;
+ switch (semantic.reg.reg.type)
+ {
+ /* Vshader: mark attributes used
+ * Pshader: mark 3.0 input registers used, save token */
+ case WINED3DSPR_INPUT:
+ if (!pshader) reg_maps->attributes[semantic.reg.reg.idx] = 1;
+ else reg_maps->packed_input[semantic.reg.reg.idx] = 1;
+ semantics_in[semantic.reg.reg.idx] = semantic;
+ break;
+
+ /* Vshader: mark 3.0 output registers used, save token */
+ case WINED3DSPR_OUTPUT:
+ reg_maps->packed_output[semantic.reg.reg.idx] = 1;
+ semantics_out[semantic.reg.reg.idx] = semantic;
+ if (semantic.usage == WINED3DDECLUSAGE_FOG) reg_maps->fog = 1;
+ break;
+
+ /* Save sampler usage token */
+ case WINED3DSPR_SAMPLER:
+ reg_maps->sampler_type[semantic.reg.reg.idx] = semantic.sampler_type;
+ break;
- } else if (WINED3DSIO_DEF == curOpcode->opcode) {
+ default:
+ TRACE("Not recording DCL register type %#x.\n", semantic.reg.reg.type);
+ break;
+ }
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEF)
+ {
+ struct wined3d_shader_dst_param dst;
+ struct wined3d_shader_src_param rel_addr;
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
if (!lconst) return E_OUTOFMEMORY;
- lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
- memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD));
+
+ fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+ lconst->idx = dst.reg.idx;
+
+ memcpy(lconst->value, pToken, 4 * sizeof(DWORD));
+ pToken += 4;
/* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
- if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1 && pshader)
+ if (shader_version.major == 1 && pshader)
{
float *value = (float *) lconst->value;
if(value[0] < -1.0) value[0] = -1.0;
}
list_add_head(&This->baseShader.constantsF, &lconst->entry);
- pToken += curOpcode->num_params;
-
- } else if (WINED3DSIO_DEFI == curOpcode->opcode) {
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFI)
+ {
+ struct wined3d_shader_dst_param dst;
+ struct wined3d_shader_src_param rel_addr;
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
if (!lconst) return E_OUTOFMEMORY;
- lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
- memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD));
- list_add_head(&This->baseShader.constantsI, &lconst->entry);
- pToken += curOpcode->num_params;
- } else if (WINED3DSIO_DEFB == curOpcode->opcode) {
+ fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+ lconst->idx = dst.reg.idx;
+
+ memcpy(lconst->value, pToken, 4 * sizeof(DWORD));
+ pToken += 4;
+
+ list_add_head(&This->baseShader.constantsI, &lconst->entry);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFB)
+ {
+ struct wined3d_shader_dst_param dst;
+ struct wined3d_shader_src_param rel_addr;
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
if (!lconst) return E_OUTOFMEMORY;
- lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
- memcpy(lconst->value, pToken + 1, 1 * sizeof(DWORD));
- list_add_head(&This->baseShader.constantsB, &lconst->entry);
- pToken += curOpcode->num_params;
+ fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+ lconst->idx = dst.reg.idx;
+
+ memcpy(lconst->value, pToken, sizeof(DWORD));
+ ++pToken;
+
+ list_add_head(&This->baseShader.constantsB, &lconst->entry);
+ }
/* If there's a loop in the shader */
- } else if (WINED3DSIO_LOOP == curOpcode->opcode ||
- WINED3DSIO_REP == curOpcode->opcode) {
+ else if (ins.handler_idx == WINED3DSIH_LOOP
+ || ins.handler_idx == WINED3DSIH_REP)
+ {
+ struct wined3d_shader_src_param src, rel_addr;
+
+ fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
+
+ /* Rep and Loop always use an integer constant for the control parameters */
+ if (ins.handler_idx == WINED3DSIH_REP)
+ {
+ reg_maps->integer_constants |= 1 << src.reg.idx;
+ }
+ else
+ {
+ fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
+ reg_maps->integer_constants |= 1 << src.reg.idx;
+ }
+
cur_loop_depth++;
if(cur_loop_depth > max_loop_depth)
max_loop_depth = cur_loop_depth;
- pToken += curOpcode->num_params;
-
- /* Rep and Loop always use an integer constant for the control parameters */
- This->baseShader.uses_int_consts = TRUE;
- } else if (WINED3DSIO_ENDLOOP == curOpcode->opcode ||
- WINED3DSIO_ENDREP == curOpcode->opcode) {
+ }
+ else if (ins.handler_idx == WINED3DSIH_ENDLOOP
+ || ins.handler_idx == WINED3DSIH_ENDREP)
+ {
cur_loop_depth--;
-
+ }
/* For subroutine prototypes */
- } else if (WINED3DSIO_LABEL == curOpcode->opcode) {
-
- DWORD snum = *pToken & WINED3DSP_REGNUM_MASK;
- reg_maps->labels[snum] = 1;
- pToken += curOpcode->num_params;
+ else if (ins.handler_idx == WINED3DSIH_LABEL)
+ {
+ struct wined3d_shader_src_param src, rel_addr;
+ fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
+ reg_maps->labels[src.reg.idx] = 1;
+ }
/* Set texture, address, temporary registers */
- } else {
+ else
+ {
int i, limit;
- /* Declare 1.X samplers implicitly, based on the destination reg. number */
- if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1
- && pshader /* Filter different instructions with the same enum values in VS */
- && (WINED3DSIO_TEX == curOpcode->opcode
- || WINED3DSIO_TEXBEM == curOpcode->opcode
- || WINED3DSIO_TEXBEML == curOpcode->opcode
- || WINED3DSIO_TEXDP3TEX == curOpcode->opcode
- || WINED3DSIO_TEXM3x2TEX == curOpcode->opcode
- || WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode
- || WINED3DSIO_TEXM3x3TEX == curOpcode->opcode
- || WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode
- || WINED3DSIO_TEXREG2AR == curOpcode->opcode
- || WINED3DSIO_TEXREG2GB == curOpcode->opcode
- || WINED3DSIO_TEXREG2RGB == curOpcode->opcode))
- {
- /* Fake sampler usage, only set reserved bit and ttype */
- DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK;
-
- TRACE("Setting fake 2D sampler for 1.x pixelshader\n");
- reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-
- /* texbem is only valid with < 1.4 pixel shaders */
- if(WINED3DSIO_TEXBEM == curOpcode->opcode ||
- WINED3DSIO_TEXBEML == curOpcode->opcode) {
- reg_maps->bumpmat[sampler_code] = TRUE;
- if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
- reg_maps->luminanceparams[sampler_code] = TRUE;
- }
- }
- }
- if(WINED3DSIO_NRM == curOpcode->opcode) {
- reg_maps->usesnrm = 1;
- } else if(WINED3DSIO_BEM == curOpcode->opcode && pshader) {
- DWORD regnum = *pToken & WINED3DSP_REGNUM_MASK;
- reg_maps->bumpmat[regnum] = TRUE;
- } else if(WINED3DSIO_DSY == curOpcode->opcode) {
- reg_maps->usesdsy = 1;
- }
-
/* This will loop over all the registers and try to
- * make a bitmask of the ones we're interested in.
+ * make a bitmask of the ones we're interested in.
*
- * Relative addressing tokens are ignored, but that's
- * okay, since we'll catch any address registers when
+ * Relative addressing tokens are ignored, but that's
+ * okay, since we'll catch any address registers when
* they are initialized (required by spec) */
- limit = (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)?
- curOpcode->num_params + 1: curOpcode->num_params;
-
- for (i = 0; i < limit; ++i) {
-
- DWORD param, addr_token, reg, regtype;
- pToken += shader_get_param(pToken, shader_version, ¶m, &addr_token);
-
- regtype = shader_get_regtype(param);
- reg = param & WINED3DSP_REGNUM_MASK;
+ if (ins.dst_count)
+ {
+ struct wined3d_shader_dst_param dst_param;
+ struct wined3d_shader_src_param dst_rel_addr;
- if (WINED3DSPR_TEXTURE == regtype) { /* vs: WINED3DSPR_ADDR */
+ fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
- if (pshader)
- reg_maps->texcoord[reg] = 1;
- else
- reg_maps->address[reg] = 1;
+ /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
+ * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
+ * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
+ if (!pshader && shader_version.major < 3 && dst_param.reg.type == WINED3DSPR_TEXCRDOUT)
+ {
+ reg_maps->texcoord_mask[dst_param.reg.type] |= dst_param.write_mask;
}
-
- else if (WINED3DSPR_TEMP == regtype)
- reg_maps->temporary[reg] = 1;
-
- else if (WINED3DSPR_INPUT == regtype) {
- if( !pshader)
- reg_maps->attributes[reg] = 1;
- else {
- if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
- /* If relative addressing is used, we must assume that all registers
- * are used. Even if it is a construct like v3[aL], we can't assume
- * that v0, v1 and v2 aren't read because aL can be negative
- */
- unsigned int i;
- for(i = 0; i < MAX_REG_INPUT; i++) {
- ((IWineD3DPixelShaderImpl *) This)->input_reg_used[i] = TRUE;
- }
- } else {
- ((IWineD3DPixelShaderImpl *) This)->input_reg_used[reg] = TRUE;
- }
- }
+ else
+ {
+ shader_record_register_usage(This, reg_maps, dst_param.reg.type,
+ dst_param.reg.idx, !!dst_param.reg.rel_addr, pshader);
}
- else if (WINED3DSPR_RASTOUT == regtype && reg == 1)
- reg_maps->fog = 1;
+ /* Declare 1.X samplers implicitly, based on the destination reg. number */
+ if (shader_version.major == 1
+ && pshader /* Filter different instructions with the same enum values in VS */
+ && (ins.handler_idx == WINED3DSIH_TEX
+ || ins.handler_idx == WINED3DSIH_TEXBEM
+ || ins.handler_idx == WINED3DSIH_TEXBEML
+ || ins.handler_idx == WINED3DSIH_TEXDP3TEX
+ || ins.handler_idx == WINED3DSIH_TEXM3x2TEX
+ || ins.handler_idx == WINED3DSIH_TEXM3x3SPEC
+ || ins.handler_idx == WINED3DSIH_TEXM3x3TEX
+ || ins.handler_idx == WINED3DSIH_TEXM3x3VSPEC
+ || ins.handler_idx == WINED3DSIH_TEXREG2AR
+ || ins.handler_idx == WINED3DSIH_TEXREG2GB
+ || ins.handler_idx == WINED3DSIH_TEXREG2RGB))
+ {
+ /* Fake sampler usage, only set reserved bit and ttype */
+ DWORD sampler_code = dst_param.reg.idx;
- else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader)
- reg_maps->vpos = 1;
+ TRACE("Setting fake 2D sampler for 1.x pixelshader\n");
+ reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D;
- else if(WINED3DSPR_CONST == regtype) {
- if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
- if(!pshader) {
- if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) {
- ((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg;
- } else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) {
- ((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg;
- }
+ /* texbem is only valid with < 1.4 pixel shaders */
+ if (ins.handler_idx == WINED3DSIH_TEXBEM
+ || ins.handler_idx == WINED3DSIH_TEXBEML)
+ {
+ reg_maps->bumpmat[sampler_code] = TRUE;
+ if (ins.handler_idx == WINED3DSIH_TEXBEML)
+ {
+ reg_maps->luminanceparams[sampler_code] = TRUE;
}
- reg_maps->usesrelconstF = TRUE;
}
}
- else if(WINED3DSPR_CONSTINT == regtype) {
- This->baseShader.uses_int_consts = TRUE;
- }
- else if(WINED3DSPR_CONSTBOOL == regtype) {
- This->baseShader.uses_bool_consts = TRUE;
+ else if (pshader && ins.handler_idx == WINED3DSIH_BEM)
+ {
+ reg_maps->bumpmat[dst_param.reg.idx] = TRUE;
}
+ }
- /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and is used
- * in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT
- * isn't used in them, but future register types might cause issues
- */
- else if (WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */
- && !pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3)
+ if (ins.handler_idx == WINED3DSIH_NRM)
+ {
+ reg_maps->usesnrm = 1;
+ }
+ else if (ins.handler_idx == WINED3DSIH_DSY)
+ {
+ reg_maps->usesdsy = 1;
+ }
+ else if(ins.handler_idx == WINED3DSIH_TEXLDD)
+ {
+ reg_maps->usestexldd = 1;
+ }
+
+ limit = ins.src_count + (ins.predicate ? 1 : 0);
+ for (i = 0; i < limit; ++i)
+ {
+ struct wined3d_shader_src_param src_param, src_rel_addr;
+
+ fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
+ switch(get_instr_regcount(ins.handler_idx, i))
{
- reg_maps->texcoord_mask[reg] |= shader_get_writemask(param);
+ case 4:
+ shader_record_register_usage(This, reg_maps, src_param.reg.type,
+ src_param.reg.idx + 3, !!src_param.reg.rel_addr, pshader);
+ /* drop through */
+ case 3:
+ shader_record_register_usage(This, reg_maps, src_param.reg.type,
+ src_param.reg.idx + 2, !!src_param.reg.rel_addr, pshader);
+ /* drop through */
+ case 2:
+ shader_record_register_usage(This, reg_maps, src_param.reg.type,
+ src_param.reg.idx + 1, !!src_param.reg.rel_addr, pshader);
+ /* drop through */
+ case 1:
+ shader_record_register_usage(This, reg_maps, src_param.reg.type,
+ src_param.reg.idx, !!src_param.reg.rel_addr, pshader);
}
}
}
}
- ++pToken;
reg_maps->loop_depth = max_loop_depth;
This->baseShader.functionLength = ((char *)pToken - (char *)byte_code);
return WINED3D_OK;
}
-static void shader_dump_decl_usage(DWORD decl, DWORD param, DWORD shader_version)
+static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic,
+ const struct wined3d_shader_version *shader_version)
{
- DWORD regtype = shader_get_regtype(param);
-
TRACE("dcl");
- if (regtype == WINED3DSPR_SAMPLER) {
- DWORD ttype = decl & WINED3DSP_TEXTURETYPE_MASK;
-
- switch (ttype) {
+ if (semantic->reg.reg.type == WINED3DSPR_SAMPLER)
+ {
+ switch (semantic->sampler_type)
+ {
case WINED3DSTT_2D: TRACE("_2d"); break;
case WINED3DSTT_CUBE: TRACE("_cube"); break;
case WINED3DSTT_VOLUME: TRACE("_volume"); break;
- default: TRACE("_unknown_ttype(0x%08x)", ttype);
- }
-
- } else {
-
- DWORD usage = decl & WINED3DSP_DCL_USAGE_MASK;
- DWORD idx = (decl & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-
+ default: TRACE("_unknown_ttype(0x%08x)", semantic->sampler_type);
+ }
+ }
+ else
+ {
/* Pixel shaders 3.0 don't have usage semantics */
- if (shader_is_pshader_version(shader_version) && shader_version < WINED3DPS_VERSION(3,0))
+ if (shader_is_pshader_version(shader_version->type) && shader_version->major < 3)
return;
else
TRACE("_");
- switch(usage) {
- case WINED3DDECLUSAGE_POSITION:
- TRACE("position%d", idx);
- break;
- case WINED3DDECLUSAGE_BLENDINDICES:
- TRACE("blend");
- break;
- case WINED3DDECLUSAGE_BLENDWEIGHT:
- TRACE("weight");
- break;
- case WINED3DDECLUSAGE_NORMAL:
- TRACE("normal%d", idx);
- break;
- case WINED3DDECLUSAGE_PSIZE:
- TRACE("psize");
- break;
- case WINED3DDECLUSAGE_COLOR:
- if(idx == 0) {
- TRACE("color");
- } else {
- TRACE("specular%d", (idx - 1));
- }
- break;
- case WINED3DDECLUSAGE_TEXCOORD:
- TRACE("texture%d", idx);
- break;
- case WINED3DDECLUSAGE_TANGENT:
- TRACE("tangent");
- break;
- case WINED3DDECLUSAGE_BINORMAL:
- TRACE("binormal");
- break;
- case WINED3DDECLUSAGE_TESSFACTOR:
- TRACE("tessfactor");
- break;
- case WINED3DDECLUSAGE_POSITIONT:
- TRACE("positionT%d", idx);
- break;
- case WINED3DDECLUSAGE_FOG:
- TRACE("fog");
- break;
- case WINED3DDECLUSAGE_DEPTH:
- TRACE("depth");
- break;
- case WINED3DDECLUSAGE_SAMPLE:
- TRACE("sample");
- break;
- default:
- FIXME("unknown_semantics(0x%08x)", usage);
+ switch (semantic->usage)
+ {
+ case WINED3DDECLUSAGE_POSITION:
+ TRACE("position%d", semantic->usage_idx);
+ break;
+ case WINED3DDECLUSAGE_BLENDINDICES:
+ TRACE("blend");
+ break;
+ case WINED3DDECLUSAGE_BLENDWEIGHT:
+ TRACE("weight");
+ break;
+ case WINED3DDECLUSAGE_NORMAL:
+ TRACE("normal%d", semantic->usage_idx);
+ break;
+ case WINED3DDECLUSAGE_PSIZE:
+ TRACE("psize");
+ break;
+ case WINED3DDECLUSAGE_COLOR:
+ if (semantic->usage_idx == 0) TRACE("color");
+ else TRACE("specular%d", (semantic->usage_idx - 1));
+ break;
+ case WINED3DDECLUSAGE_TEXCOORD:
+ TRACE("texture%d", semantic->usage_idx);
+ break;
+ case WINED3DDECLUSAGE_TANGENT:
+ TRACE("tangent");
+ break;
+ case WINED3DDECLUSAGE_BINORMAL:
+ TRACE("binormal");
+ break;
+ case WINED3DDECLUSAGE_TESSFACTOR:
+ TRACE("tessfactor");
+ break;
+ case WINED3DDECLUSAGE_POSITIONT:
+ TRACE("positionT%d", semantic->usage_idx);
+ break;
+ case WINED3DDECLUSAGE_FOG:
+ TRACE("fog");
+ break;
+ case WINED3DDECLUSAGE_DEPTH:
+ TRACE("depth");
+ break;
+ case WINED3DDECLUSAGE_SAMPLE:
+ TRACE("sample");
+ break;
+ default:
+ FIXME("unknown_semantics(0x%08x)", semantic->usage);
}
}
}
-static void shader_dump_arr_entry(const DWORD param, const DWORD addr_token,
- unsigned int reg, int input, DWORD shader_version)
-{
- char relative =
- ((param & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE);
-
- if (relative) {
- TRACE("[");
- if (addr_token)
- shader_dump_param(addr_token, 0, input, shader_version);
- else
- TRACE("a0.x");
- TRACE(" + ");
- }
- TRACE("%u", reg);
- if (relative)
- TRACE("]");
-}
-
-static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version)
+static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx,
+ enum wined3d_immconst_type immconst_type, const DWORD *immconst_data,
+ const struct wined3d_shader_src_param *rel_addr, const struct wined3d_shader_version *shader_version)
{
- static const char * const rastout_reg_names[] = { "oPos", "oFog", "oPts" };
- static const char * const misctype_reg_names[] = { "vPos", "vFace"};
- const char *swizzle_reg_chars = "xyzw";
-
- DWORD reg = param & WINED3DSP_REGNUM_MASK;
- DWORD regtype = shader_get_regtype(param);
- DWORD modifier = param & WINED3DSP_SRCMOD_MASK;
+ static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
+ static const char * const misctype_reg_names[] = {"vPos", "vFace"};
+ UINT offset = register_idx;
- /* There are some minor differences between pixel and vertex shaders */
- char pshader = shader_is_pshader_version(shader_version);
-
- if (input) {
- if ( (modifier == WINED3DSPSM_NEG) ||
- (modifier == WINED3DSPSM_BIASNEG) ||
- (modifier == WINED3DSPSM_SIGNNEG) ||
- (modifier == WINED3DSPSM_X2NEG) ||
- (modifier == WINED3DSPSM_ABSNEG) )
- TRACE("-");
- else if (modifier == WINED3DSPSM_COMP)
- TRACE("1-");
- else if (modifier == WINED3DSPSM_NOT)
- TRACE("!");
-
- if (modifier == WINED3DSPSM_ABS || modifier == WINED3DSPSM_ABSNEG)
- TRACE("abs(");
- }
-
- switch (regtype) {
+ switch (register_type)
+ {
case WINED3DSPR_TEMP:
- TRACE("r%u", reg);
+ TRACE("r");
break;
+
case WINED3DSPR_INPUT:
TRACE("v");
- shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
break;
+
case WINED3DSPR_CONST:
case WINED3DSPR_CONST2:
case WINED3DSPR_CONST3:
case WINED3DSPR_CONST4:
TRACE("c");
- shader_dump_arr_entry(param, addr_token, shader_get_float_offset(param), input, shader_version);
+ offset = shader_get_float_offset(register_type, register_idx);
break;
- case WINED3DSPR_TEXTURE: /* vs: case D3DSPR_ADDR */
- TRACE("%c%u", (pshader? 't':'a'), reg);
- break;
+
+ case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
+ TRACE("%c", shader_is_pshader_version(shader_version->type) ? 't' : 'a');
+ break;
+
case WINED3DSPR_RASTOUT:
- TRACE("%s", rastout_reg_names[reg]);
+ TRACE("%s", rastout_reg_names[register_idx]);
break;
+
case WINED3DSPR_COLOROUT:
- TRACE("oC%u", reg);
+ TRACE("oC");
break;
+
case WINED3DSPR_DEPTHOUT:
TRACE("oDepth");
break;
+
case WINED3DSPR_ATTROUT:
- TRACE("oD%u", reg);
+ TRACE("oD");
break;
- case WINED3DSPR_TEXCRDOUT:
+ case WINED3DSPR_TEXCRDOUT:
/* Vertex shaders >= 3.0 use general purpose output registers
* (WINED3DSPR_OUTPUT), which can include an address token */
-
- if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) {
- TRACE("o");
- shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
- }
- else
- TRACE("oT%u", reg);
+ if (shader_version->major >= 3) TRACE("o");
+ else TRACE("oT");
break;
+
case WINED3DSPR_CONSTINT:
TRACE("i");
- shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
break;
+
case WINED3DSPR_CONSTBOOL:
TRACE("b");
- shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
break;
+
case WINED3DSPR_LABEL:
- TRACE("l%u", reg);
+ TRACE("l");
break;
+
case WINED3DSPR_LOOP:
TRACE("aL");
break;
+
case WINED3DSPR_SAMPLER:
- TRACE("s%u", reg);
+ TRACE("s");
break;
+
case WINED3DSPR_MISCTYPE:
- if (reg > 1) {
- FIXME("Unhandled misctype register %d\n", reg);
- } else {
- TRACE("%s", misctype_reg_names[reg]);
- }
+ if (register_idx > 1) FIXME("Unhandled misctype register %d\n", register_idx);
+ else TRACE("%s", misctype_reg_names[register_idx]);
break;
+
case WINED3DSPR_PREDICATE:
- TRACE("p%u", reg);
+ TRACE("p");
break;
+
+ case WINED3DSPR_IMMCONST:
+ TRACE("l");
+ break;
+
default:
- TRACE("unhandled_rtype(%#x)", regtype);
+ TRACE("unhandled_rtype(%#x)", register_type);
break;
- }
-
- if (!input) {
- /* operand output (for modifiers and shift, see dump_ins_modifiers) */
-
- if ((param & WINED3DSP_WRITEMASK_ALL) != WINED3DSP_WRITEMASK_ALL) {
- TRACE(".");
- if (param & WINED3DSP_WRITEMASK_0) TRACE("%c", swizzle_reg_chars[0]);
- if (param & WINED3DSP_WRITEMASK_1) TRACE("%c", swizzle_reg_chars[1]);
- if (param & WINED3DSP_WRITEMASK_2) TRACE("%c", swizzle_reg_chars[2]);
- if (param & WINED3DSP_WRITEMASK_3) TRACE("%c", swizzle_reg_chars[3]);
- }
-
- } else {
- /** operand input */
- DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+ }
+
+ if (register_type == WINED3DSPR_IMMCONST)
+ {
+ TRACE("(");
+ switch (immconst_type)
+ {
+ case WINED3D_IMMCONST_FLOAT:
+ TRACE("%.8e", *(float *)immconst_data);
+ break;
+
+ case WINED3D_IMMCONST_FLOAT4:
+ TRACE("%.8e, %.8e, %.8e, %.8e",
+ *(float *)&immconst_data[0], *(float *)&immconst_data[1],
+ *(float *)&immconst_data[2], *(float *)&immconst_data[3]);
+ break;
+
+ default:
+ TRACE("<unhandled immconst_type %#x>", immconst_type);
+ break;
+ }
+ TRACE(")");
+ }
+ else if (register_type != WINED3DSPR_RASTOUT && register_type != WINED3DSPR_MISCTYPE)
+ {
+ if (rel_addr)
+ {
+ TRACE("[");
+ shader_dump_src_param(rel_addr, shader_version);
+ TRACE(" + ");
+ }
+ TRACE("%u", offset);
+ if (rel_addr) TRACE("]");
+ }
+}
+
+void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
+ const struct wined3d_shader_version *shader_version)
+{
+ DWORD write_mask = param->write_mask;
+
+ shader_dump_register(param->reg.type, param->reg.idx, 0, NULL, param->reg.rel_addr, shader_version);
+
+ if (write_mask != WINED3DSP_WRITEMASK_ALL)
+ {
+ static const char *write_mask_chars = "xyzw";
+
+ TRACE(".");
+ if (write_mask & WINED3DSP_WRITEMASK_0) TRACE("%c", write_mask_chars[0]);
+ if (write_mask & WINED3DSP_WRITEMASK_1) TRACE("%c", write_mask_chars[1]);
+ if (write_mask & WINED3DSP_WRITEMASK_2) TRACE("%c", write_mask_chars[2]);
+ if (write_mask & WINED3DSP_WRITEMASK_3) TRACE("%c", write_mask_chars[3]);
+ }
+}
+
+void shader_dump_src_param(const struct wined3d_shader_src_param *param,
+ const struct wined3d_shader_version *shader_version)
+{
+ DWORD src_modifier = param->modifiers;
+ DWORD swizzle = param->swizzle;
+
+ if (src_modifier == WINED3DSPSM_NEG
+ || src_modifier == WINED3DSPSM_BIASNEG
+ || src_modifier == WINED3DSPSM_SIGNNEG
+ || src_modifier == WINED3DSPSM_X2NEG
+ || src_modifier == WINED3DSPSM_ABSNEG)
+ TRACE("-");
+ else if (src_modifier == WINED3DSPSM_COMP)
+ TRACE("1-");
+ else if (src_modifier == WINED3DSPSM_NOT)
+ TRACE("!");
+
+ if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG)
+ TRACE("abs(");
+
+ shader_dump_register(param->reg.type, param->reg.idx, param->reg.immconst_type,
+ param->reg.immconst_data, param->reg.rel_addr, shader_version);
+
+ if (src_modifier)
+ {
+ switch (src_modifier)
+ {
+ case WINED3DSPSM_NONE: break;
+ case WINED3DSPSM_NEG: break;
+ case WINED3DSPSM_NOT: break;
+ case WINED3DSPSM_BIAS: TRACE("_bias"); break;
+ case WINED3DSPSM_BIASNEG: TRACE("_bias"); break;
+ case WINED3DSPSM_SIGN: TRACE("_bx2"); break;
+ case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break;
+ case WINED3DSPSM_COMP: break;
+ case WINED3DSPSM_X2: TRACE("_x2"); break;
+ case WINED3DSPSM_X2NEG: TRACE("_x2"); break;
+ case WINED3DSPSM_DZ: TRACE("_dz"); break;
+ case WINED3DSPSM_DW: TRACE("_dw"); break;
+ case WINED3DSPSM_ABSNEG: TRACE(")"); break;
+ case WINED3DSPSM_ABS: TRACE(")"); break;
+ default:
+ TRACE("_unknown_modifier(%#x)", src_modifier);
+ }
+ }
+
+ if (swizzle != WINED3DSP_NOSWIZZLE)
+ {
+ static const char *swizzle_chars = "xyzw";
DWORD swizzle_x = swizzle & 0x03;
DWORD swizzle_y = (swizzle >> 2) & 0x03;
DWORD swizzle_z = (swizzle >> 4) & 0x03;
DWORD swizzle_w = (swizzle >> 6) & 0x03;
- if (0 != modifier) {
- switch (modifier) {
- case WINED3DSPSM_NONE: break;
- case WINED3DSPSM_NEG: break;
- case WINED3DSPSM_NOT: break;
- case WINED3DSPSM_BIAS: TRACE("_bias"); break;
- case WINED3DSPSM_BIASNEG: TRACE("_bias"); break;
- case WINED3DSPSM_SIGN: TRACE("_bx2"); break;
- case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break;
- case WINED3DSPSM_COMP: break;
- case WINED3DSPSM_X2: TRACE("_x2"); break;
- case WINED3DSPSM_X2NEG: TRACE("_x2"); break;
- case WINED3DSPSM_DZ: TRACE("_dz"); break;
- case WINED3DSPSM_DW: TRACE("_dw"); break;
- case WINED3DSPSM_ABSNEG: TRACE(")"); break;
- case WINED3DSPSM_ABS: TRACE(")"); break;
- default:
- TRACE("_unknown_modifier(%#x)", modifier >> WINED3DSP_SRCMOD_SHIFT);
- }
+ if (swizzle_x == swizzle_y
+ && swizzle_x == swizzle_z
+ && swizzle_x == swizzle_w)
+ {
+ TRACE(".%c", swizzle_chars[swizzle_x]);
}
-
- /**
- * swizzle bits fields:
- * RRGGBBAA
- */
- if ((WINED3DVS_NOSWIZZLE >> WINED3DVS_SWIZZLE_SHIFT) != swizzle) {
- if (swizzle_x == swizzle_y &&
- swizzle_x == swizzle_z &&
- swizzle_x == swizzle_w) {
- TRACE(".%c", swizzle_reg_chars[swizzle_x]);
- } else {
- TRACE(".%c%c%c%c",
- swizzle_reg_chars[swizzle_x],
- swizzle_reg_chars[swizzle_y],
- swizzle_reg_chars[swizzle_z],
- swizzle_reg_chars[swizzle_w]);
- }
+ else
+ {
+ TRACE(".%c%c%c%c", swizzle_chars[swizzle_x], swizzle_chars[swizzle_y],
+ swizzle_chars[swizzle_z], swizzle_chars[swizzle_w]);
}
}
}
/* Shared code in order to generate the bulk of the shader string.
* NOTE: A description of how to parse tokens can be found on msdn */
-void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
- const shader_reg_maps* reg_maps, CONST DWORD* pFunction)
+void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
+ const shader_reg_maps *reg_maps, const DWORD *pFunction)
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
- const SHADER_OPCODE *opcode_table = This->baseShader.shader_ins;
const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table;
- DWORD shader_version = reg_maps->shader_version;
+ const struct wined3d_shader_frontend *fe = This->baseShader.frontend;
+ void *fe_data = This->baseShader.frontend_data;
+ struct wined3d_shader_src_param src_rel_addr[4];
+ struct wined3d_shader_src_param src_param[4];
+ struct wined3d_shader_version shader_version;
+ struct wined3d_shader_src_param dst_rel_addr;
struct wined3d_shader_dst_param dst_param;
struct wined3d_shader_instruction ins;
+ struct wined3d_shader_context ctx;
const DWORD *pToken = pFunction;
- const SHADER_OPCODE *curOpcode;
SHADER_HANDLER hw_fct;
DWORD i;
/* Initialize current parsing state */
- ins.shader = iface;
- ins.buffer = buffer;
- ins.reg_maps = reg_maps;
+ ctx.shader = iface;
+ ctx.reg_maps = reg_maps;
+ ctx.buffer = buffer;
+
+ ins.ctx = &ctx;
ins.dst = &dst_param;
+ ins.src = src_param;
This->baseShader.parse_state.current_row = 0;
- while (WINED3DPS_END() != *pToken)
- {
- DWORD opcode_token;
+ fe->shader_read_header(fe_data, &pToken, &shader_version);
- /* Skip version token */
- if (shader_is_version_token(*pToken))
- {
- ++pToken;
- continue;
- }
+ while (!fe->shader_is_end(fe_data, &pToken))
+ {
+ const char *comment;
+ UINT param_size;
/* Skip comment tokens */
- if (shader_is_comment(*pToken))
- {
- pToken += (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
- ++pToken;
- continue;
- }
+ fe->shader_read_comment(&pToken, &comment);
+ if (comment) continue;
/* Read opcode */
- opcode_token = *pToken++;
- curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token);
+ fe->shader_read_opcode(fe_data, &pToken, &ins, ¶m_size);
/* Unknown opcode and its parameters */
- if (!curOpcode)
+ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
{
- FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
- pToken += shader_skip_unrecognized(pToken, shader_version);
+ TRACE("Skipping unrecognized instruction.\n");
+ pToken += param_size;
continue;
}
/* Nothing to do */
- if (WINED3DSIO_DCL == curOpcode->opcode
- || WINED3DSIO_NOP == curOpcode->opcode
- || WINED3DSIO_DEF == curOpcode->opcode
- || WINED3DSIO_DEFI == curOpcode->opcode
- || WINED3DSIO_DEFB == curOpcode->opcode
- || WINED3DSIO_PHASE == curOpcode->opcode
- || WINED3DSIO_RET == curOpcode->opcode)
+ if (ins.handler_idx == WINED3DSIH_DCL
+ || ins.handler_idx == WINED3DSIH_NOP
+ || ins.handler_idx == WINED3DSIH_DEF
+ || ins.handler_idx == WINED3DSIH_DEFI
+ || ins.handler_idx == WINED3DSIH_DEFB
+ || ins.handler_idx == WINED3DSIH_PHASE
+ || ins.handler_idx == WINED3DSIH_RET)
{
- pToken += shader_skip_opcode(curOpcode, opcode_token, shader_version);
+ pToken += param_size;
continue;
}
/* Select handler */
- hw_fct = handler_table[curOpcode->handler_idx];
+ hw_fct = handler_table[ins.handler_idx];
/* Unhandled opcode */
if (!hw_fct)
{
- FIXME("Can't handle opcode %s in hwShader\n", curOpcode->name);
- pToken += shader_skip_opcode(curOpcode, opcode_token, shader_version);
+ FIXME("Backend can't handle opcode %#x\n", ins.handler_idx);
+ pToken += param_size;
continue;
}
- ins.handler_idx = curOpcode->handler_idx;
- ins.flags = opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK;
- ins.coissue = opcode_token & WINED3DSI_COISSUE;
-
/* Destination token */
- ins.dst_count = curOpcode->dst_token ? 1 : 0;
- if (ins.dst_count)
- {
- DWORD param, addr_param = 0;
- pToken += shader_get_param(pToken, shader_version, ¶m, &addr_param);
- shader_parse_dst_param(param, addr_param, &dst_param);
- }
+ if (ins.dst_count) fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
/* Predication token */
- if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) ins.predicate = *pToken++;
+ if (ins.predicate) ins.predicate = *pToken++;
/* Other source tokens */
- ins.src_count = curOpcode->num_params - curOpcode->dst_token;
for (i = 0; i < ins.src_count; ++i)
{
- DWORD param, addr_token = 0;
- pToken += shader_get_param(pToken, shader_version, ¶m, &addr_token);
- ins.src[i] = param;
- ins.src_addr[i] = addr_token;
+ fe->shader_read_src_param(fe_data, &pToken, &src_param[i], &src_rel_addr[i]);
}
/* Call appropriate function for output target */
hw_fct(&ins);
/* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
- /* FIXME: This should be internal to the shader backend.
- * Also, right now this is the only reason "shader_mode" exists. */
- if (This->baseShader.shader_mode == SHADER_GLSL) shader_glsl_add_instruction_modifiers(&ins);
+ device->shader_backend->shader_add_instruction_modifiers(&ins);
}
}
-static void shader_dump_ins_modifiers(const DWORD output)
+static void shader_dump_ins_modifiers(const struct wined3d_shader_dst_param *dst)
{
- DWORD shift = (output & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
- DWORD mmask = output & WINED3DSP_DSTMOD_MASK;
+ DWORD mmask = dst->modifiers;
- switch (shift) {
+ switch (dst->shift)
+ {
case 0: break;
case 13: TRACE("_d8"); break;
case 14: TRACE("_d4"); break;
case 1: TRACE("_x2"); break;
case 2: TRACE("_x4"); break;
case 3: TRACE("_x8"); break;
- default: TRACE("_unhandled_shift(%d)", shift); break;
+ default: TRACE("_unhandled_shift(%d)", dst->shift); break;
}
if (mmask & WINED3DSPDM_SATURATE) TRACE("_sat");
mmask &= ~(WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_MSAMPCENTROID);
if (mmask)
- FIXME("_unrecognized_modifier(%#x)", mmask >> WINED3DSP_DSTMOD_SHIFT);
+ FIXME("_unrecognized_modifier(%#x)", mmask);
}
-void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table)
+void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction)
{
+ struct wined3d_shader_version shader_version;
const DWORD* pToken = pFunction;
- const SHADER_OPCODE* curOpcode = NULL;
- DWORD shader_version;
- DWORD opcode_token;
DWORD i;
TRACE("Parsing %p\n", pFunction);
- /* The version token is supposed to be the first token */
- if (!shader_is_version_token(*pToken))
- {
- FIXME("First token is not a version token, invalid shader.\n");
- return;
- }
- shader_version = *pToken++;
- TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version) ? "ps": "vs",
- WINED3DSHADER_VERSION_MAJOR(shader_version), WINED3DSHADER_VERSION_MINOR(shader_version));
+ fe->shader_read_header(fe_data, &pToken, &shader_version);
+
+ TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version.type) ? "ps": "vs",
+ shader_version.major, shader_version.minor);
- while (WINED3DVS_END() != *pToken)
+ while (!fe->shader_is_end(fe_data, &pToken))
{
- if (shader_is_comment(*pToken)) /* comment */
+ struct wined3d_shader_instruction ins;
+ const char *comment;
+ UINT param_size;
+
+ /* comment */
+ fe->shader_read_comment(&pToken, &comment);
+ if (comment)
{
- DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
- ++pToken;
- TRACE("//%s\n", (const char*)pToken);
- pToken += comment_len;
+ TRACE("//%s\n", comment);
+ continue;
+ }
+
+ fe->shader_read_opcode(fe_data, &pToken, &ins, ¶m_size);
+ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
+ {
+ TRACE("Skipping unrecognized instruction.\n");
+ pToken += param_size;
continue;
}
- opcode_token = *pToken++;
- curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token);
- if (!curOpcode)
+ if (ins.handler_idx == WINED3DSIH_DCL)
{
- int tokens_read;
- FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
- tokens_read = shader_skip_unrecognized(pToken, shader_version);
- pToken += tokens_read;
+ struct wined3d_shader_semantic semantic;
+
+ fe->shader_read_semantic(&pToken, &semantic);
+
+ shader_dump_decl_usage(&semantic, &shader_version);
+ shader_dump_ins_modifiers(&semantic.reg);
+ TRACE(" ");
+ shader_dump_dst_param(&semantic.reg, &shader_version);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEF)
+ {
+ struct wined3d_shader_dst_param dst;
+ struct wined3d_shader_src_param rel_addr;
+
+ fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+
+ TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(dst.reg.type, dst.reg.idx),
+ *(const float *)(pToken),
+ *(const float *)(pToken + 1),
+ *(const float *)(pToken + 2),
+ *(const float *)(pToken + 3));
+ pToken += 4;
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFI)
+ {
+ struct wined3d_shader_dst_param dst;
+ struct wined3d_shader_src_param rel_addr;
+
+ fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+
+ TRACE("defi i%u = %d, %d, %d, %d", dst.reg.idx,
+ *(pToken),
+ *(pToken + 1),
+ *(pToken + 2),
+ *(pToken + 3));
+ pToken += 4;
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFB)
+ {
+ struct wined3d_shader_dst_param dst;
+ struct wined3d_shader_src_param rel_addr;
+
+ fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+
+ TRACE("defb b%u = %s", dst.reg.idx, *pToken ? "true" : "false");
+ ++pToken;
}
else
{
- if (curOpcode->opcode == WINED3DSIO_DCL)
- {
- DWORD usage = *pToken;
- DWORD param = *(pToken + 1);
+ struct wined3d_shader_src_param dst_rel_addr, src_rel_addr;
+ struct wined3d_shader_dst_param dst_param;
+ struct wined3d_shader_src_param src_param;
- shader_dump_decl_usage(usage, param, shader_version);
- shader_dump_ins_modifiers(param);
- TRACE(" ");
- shader_dump_param(param, 0, 0, shader_version);
- pToken += 2;
- }
- else if (curOpcode->opcode == WINED3DSIO_DEF)
- {
- unsigned int offset = shader_get_float_offset(*pToken);
-
- TRACE("def c%u = %f, %f, %f, %f", offset,
- *(const float *)(pToken + 1),
- *(const float *)(pToken + 2),
- *(const float *)(pToken + 3),
- *(const float *)(pToken + 4));
- pToken += 5;
- }
- else if (curOpcode->opcode == WINED3DSIO_DEFI)
+ if (ins.dst_count)
{
- TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK,
- *(pToken + 1),
- *(pToken + 2),
- *(pToken + 3),
- *(pToken + 4));
- pToken += 5;
+ fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
}
- else if (curOpcode->opcode == WINED3DSIO_DEFB)
+
+ /* Print out predication source token first - it follows
+ * the destination token. */
+ if (ins.predicate)
{
- TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK,
- *(pToken + 1)? "true": "false");
- pToken += 2;
+ fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
+ TRACE("(");
+ shader_dump_src_param(&src_param, &shader_version);
+ TRACE(") ");
}
- else
- {
- DWORD param, addr_token;
- int tokens_read;
- /* Print out predication source token first - it follows
- * the destination token. */
- if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
- {
- TRACE("(");
- shader_dump_param(*(pToken + 2), 0, 1, shader_version);
- TRACE(") ");
- }
- if (opcode_token & WINED3DSI_COISSUE)
- {
- /* PixWin marks instructions with the coissue flag with a '+' */
- TRACE("+");
- }
+ /* PixWin marks instructions with the coissue flag with a '+' */
+ if (ins.coissue) TRACE("+");
- TRACE("%s", curOpcode->name);
+ TRACE("%s", shader_opcode_names[ins.handler_idx]);
- if (curOpcode->opcode == WINED3DSIO_IFC
- || curOpcode->opcode == WINED3DSIO_BREAKC)
- {
- DWORD op = (opcode_token & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
-
- switch (op)
- {
- case COMPARISON_GT: TRACE("_gt"); break;
- case COMPARISON_EQ: TRACE("_eq"); break;
- case COMPARISON_GE: TRACE("_ge"); break;
- case COMPARISON_LT: TRACE("_lt"); break;
- case COMPARISON_NE: TRACE("_ne"); break;
- case COMPARISON_LE: TRACE("_le"); break;
- default: TRACE("_(%u)", op);
- }
- }
- else if (curOpcode->opcode == WINED3DSIO_TEX
- && shader_version >= WINED3DPS_VERSION(2,0)
- && (opcode_token & WINED3DSI_TEXLD_PROJECT))
- {
- TRACE("p");
- }
-
- /* Destination token */
- if (curOpcode->dst_token)
- {
- tokens_read = shader_get_param(pToken, shader_version, ¶m, &addr_token);
- pToken += tokens_read;
-
- shader_dump_ins_modifiers(param);
- TRACE(" ");
- shader_dump_param(param, addr_token, 0, shader_version);
- }
-
- /* Predication token - already printed out, just skip it */
- if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
+ if (ins.handler_idx == WINED3DSIH_IFC
+ || ins.handler_idx == WINED3DSIH_BREAKC)
+ {
+ switch (ins.flags)
{
- pToken++;
+ case COMPARISON_GT: TRACE("_gt"); break;
+ case COMPARISON_EQ: TRACE("_eq"); break;
+ case COMPARISON_GE: TRACE("_ge"); break;
+ case COMPARISON_LT: TRACE("_lt"); break;
+ case COMPARISON_NE: TRACE("_ne"); break;
+ case COMPARISON_LE: TRACE("_le"); break;
+ default: TRACE("_(%u)", ins.flags);
}
+ }
+ else if (ins.handler_idx == WINED3DSIH_TEX
+ && shader_version.major >= 2
+ && (ins.flags & WINED3DSI_TEXLD_PROJECT))
+ {
+ TRACE("p");
+ }
- /* Other source tokens */
- for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i)
- {
- tokens_read = shader_get_param(pToken, shader_version, ¶m, &addr_token);
- pToken += tokens_read;
+ /* We already read the destination token, print it. */
+ if (ins.dst_count)
+ {
+ shader_dump_ins_modifiers(&dst_param);
+ TRACE(" ");
+ shader_dump_dst_param(&dst_param, &shader_version);
+ }
- TRACE((i == 0)? " " : ", ");
- shader_dump_param(param, addr_token, 1, shader_version);
- }
+ /* Other source tokens */
+ for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i)
+ {
+ fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
+ TRACE(!i ? " " : ", ");
+ shader_dump_src_param(&src_param, &shader_version);
}
- TRACE("\n");
}
+ TRACE("\n");
}
}
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_destroy(iface);
+ HeapFree(GetProcessHeap(), 0, This->baseShader.reg_maps.constf);
HeapFree(GetProcessHeap(), 0, This->baseShader.function);
shader_delete_constant_list(&This->baseShader.constantsF);
shader_delete_constant_list(&This->baseShader.constantsB);
shader_delete_constant_list(&This->baseShader.constantsI);
list_remove(&This->baseShader.shader_list_entry);
+
+ if (This->baseShader.frontend && This->baseShader.frontend_data)
+ {
+ This->baseShader.frontend->shader_free(This->baseShader.frontend_data);
+ }
}
static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
static void shader_none_free(IWineD3DDevice *iface) {}
static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;}
-static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
+static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface,
+ SHADER_BUFFER *buffer, const struct ps_compile_args *args)
+{
FIXME("NONE shader backend asked to generate a pixel shader\n");
return 0;
}
-static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
+static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface,
+ SHADER_BUFFER *buffer, const struct vs_compile_args *args)
+{
FIXME("NONE shader backend asked to generate a vertex shader\n");
return 0;
}
+static void shader_none_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {}
#define GLINFO_LOCATION (*gl_info)
static void shader_none_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
shader_none_generate_vshader,
shader_none_get_caps,
shader_none_color_fixup_supported,
+ shader_none_add_instruction_modifiers,
};
format = attrib->format_desc->format;
/* Look for newly appeared conversion */
- if (!GL_SUPPORT(NV_HALF_FLOAT) && (format == WINED3DFMT_R16G16_FLOAT || format == WINED3DFMT_R16G16B16A16_FLOAT))
+ if (!GL_SUPPORT(ARB_HALF_FLOAT_VERTEX) && (format == WINED3DFMT_R16G16_FLOAT || format == WINED3DFMT_R16G16B16A16_FLOAT))
{
ret = buffer_process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run);
/* Certain declaration types need some fixups before we can pass them to
* opengl. This means D3DCOLOR attributes with fixed function vertex
* processing, FLOAT4 POSITIONT with fixed function, and FLOAT16 if
- * GL_NV_half_float is not supported.
+ * GL_ARB_half_float_vertex is not supported.
*
* Note for d3d8 and d3d9:
* The vertex buffer FVF doesn't help with finding them, we have to use
const BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
{
- if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) return This->resource.allocatedMemory;
+ /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */
+ if(This->resource.allocatedMemory) return This->resource.allocatedMemory;
This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
{
if(count == 1)
{
+ IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
+
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
+ LEAVE_GL();
}
}
else
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
{
+ IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
+
+ ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+ ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
+ LEAVE_GL();
+
This->resource.allocatedMemory = NULL;
}
else if (This->flags & WINED3D_BUFFER_HASDESC)
}
}
- if(GL_SUPPORT(ARB_POINT_SPRITE)) {
- for(s = 0; s < GL_LIMITS(textures); s++) {
- GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
- glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
- checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
- }
+ for(s = 0; s < GL_LIMITS(point_sprite_units); s++) {
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
+ glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
+ checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
}
LEAVE_GL();
{
WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
buffer_object = 0;
- data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot])->resource.allocatedMemory;
+ data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot]);
if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride)
{
FIXME("System memory vertex data load offset is negative!\n");
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage,
- DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer, HANDLE *sharedHandle, IUnknown *parent)
+ DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
/* Dummy format for now */
return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage,
- WINED3DPOOL Pool, IWineD3DBuffer** ppIndexBuffer,
- HANDLE *sharedHandle, IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface,
+ UINT Length, DWORD Usage, WINED3DPOOL Pool, IWineD3DBuffer **ppIndexBuffer, IUnknown *parent)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info);
struct wined3d_buffer *object;
return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IWineD3DSurface **ppSurface,WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample ,DWORD MultisampleQuality, HANDLE* pSharedHandle, WINED3DSURFTYPE Impl, IUnknown *parent) {
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface,
+ UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level,
+ IWineD3DSurface **ppSurface, WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool,
+ WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, WINED3DSURFTYPE Impl, IUnknown *parent)
+{
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
unsigned int Size = 1;
const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(Format, &GLINFO_LOCATION);
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
- UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
- IWineD3DTexture **ppTexture, HANDLE *pSharedHandle, IUnknown *parent)
+ UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format,
+ WINED3DPOOL Pool, IWineD3DTexture **ppTexture, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
unsigned int pow2Height;
TRACE("(%p) : Width %d, Height %d, Levels %d, Usage %#x\n", This, Width, Height, Levels, Usage);
- TRACE("Format %#x (%s), Pool %#x, ppTexture %p, pSharedHandle %p, parent %p\n",
- Format, debug_d3dformat(Format), Pool, ppTexture, pSharedHandle, parent);
+ TRACE("Format %#x (%s), Pool %#x, ppTexture %p, parent %p\n",
+ Format, debug_d3dformat(Format), Pool, ppTexture, parent);
/* TODO: It should only be possible to create textures for formats
that are reported as supported */
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface,
- UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
- IWineD3DVolumeTexture **ppVolumeTexture, HANDLE *pSharedHandle, IUnknown *parent)
+ UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, WINED3DFORMAT Format,
+ WINED3DPOOL Pool, IWineD3DVolumeTexture **ppVolumeTexture, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
- UINT Width, UINT Height, UINT Depth,
- DWORD Usage,
- WINED3DFORMAT Format, WINED3DPOOL Pool,
- IWineD3DVolume** ppVolume,
- HANDLE* pSharedHandle, IUnknown *parent) {
-
+ UINT Width, UINT Height, UINT Depth, DWORD Usage, WINED3DFORMAT Format,
+ WINED3DPOOL Pool, IWineD3DVolume **ppVolume, IUnknown *parent)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVolumeImpl *object; /** NOTE: impl ref allowed since this is a create function **/
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &GLINFO_LOCATION);
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface,
- UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
- IWineD3DCubeTexture **ppCubeTexture, HANDLE *pSharedHandle, IUnknown *parent)
+ UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format,
+ WINED3DPOOL Pool, IWineD3DCubeTexture **ppCubeTexture, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
object->lpVtbl = &IWineD3DVertexShader_Vtbl;
object->parent = parent;
- shader_init(&object->baseShader, iface, IWineD3DVertexShaderImpl_shader_ins);
+ shader_init(&object->baseShader, iface);
list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
*ppVertexShader = (IWineD3DVertexShader *)object;
IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
}
- hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction);
+ hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, NULL);
if (FAILED(hr))
{
WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
return hr;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, CONST DWORD *pFunction, IWineD3DPixelShader **ppPixelShader, IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface,
+ const DWORD *pFunction, const struct wined3d_shader_signature *output_signature,
+ IWineD3DPixelShader **ppPixelShader, IUnknown *parent)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */
HRESULT hr = WINED3D_OK;
object->lpVtbl = &IWineD3DPixelShader_Vtbl;
object->parent = parent;
- shader_init(&object->baseShader, iface, IWineD3DPixelShaderImpl_shader_ins);
+ shader_init(&object->baseShader, iface);
list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
*ppPixelShader = (IWineD3DPixelShader *)object;
TRACE("(%p) : Created pixel shader %p\n", This, *ppPixelShader);
- hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction);
+ hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction, output_signature);
if (FAILED(hr))
{
WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
hr = IWineD3DDevice_CreateSurface((IWineD3DDevice *) This, bm.bmWidth, bm.bmHeight, WINED3DFMT_R5G6B5,
TRUE, FALSE, 0, &This->logo_surface, WINED3DRTYPE_SURFACE, 0,
- WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, NULL, SURFACE_OPENGL, NULL);
+ WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, SURFACE_OPENGL, NULL);
if(FAILED(hr)) {
ERR("Wine logo requested, but failed to create surface\n");
goto out;
}
static void device_map_psamplers(IWineD3DDeviceImpl *This) {
- const DWORD *sampler_tokens =
- ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.samplers;
+ const WINED3DSAMPLER_TEXTURE_TYPE *sampler_type =
+ ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.sampler_type;
unsigned int i;
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
- if (sampler_tokens[i] && This->texUnitMap[i] != i) {
+ if (sampler_type[i] && This->texUnitMap[i] != i)
+ {
device_map_stage(This, i, i);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
if (i < MAX_TEXTURES) {
}
static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
- const DWORD *vshader_sampler_tokens =
- ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.samplers;
- const DWORD *pshader_sampler_tokens = NULL;
+ const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
+ ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type;
+ const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
int start = GL_LIMITS(combined_samplers) - 1;
int i;
/* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
* Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
- pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers;
+ pshader_sampler_type = pshader->baseShader.reg_maps.sampler_type;
}
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
int vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
- if (vshader_sampler_tokens[i]) {
+ if (vshader_sampler_type[i])
+ {
if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
{
/* Already mapped somewhere */
}
while (start >= 0) {
- if (device_unit_free_for_vs(This, pshader_sampler_tokens, vshader_sampler_tokens, start)) {
+ if (device_unit_free_for_vs(This, pshader_sampler_type, vshader_sampler_type, start))
+ {
device_map_stage(This, vsampler_idx, start);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(vsampler_idx));
ENTER_GL();
if (dest->resource.allocatedMemory == NULL) {
- /* This may happen if we do direct locking into a vbo. Unlikely,
- * but theoretically possible(ddraw processvertices test)
- */
- dest->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), 0, dest->resource.size);
- if(!dest->resource.allocatedMemory) {
- LEAVE_GL();
- ERR("Out of memory\n");
- return E_OUTOFMEMORY;
- }
- if (dest->buffer_object)
- {
- const void *src;
- GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->buffer_object));
- checkGLcall("glBindBufferARB");
- src = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB));
- if(src) {
- memcpy(dest->resource.allocatedMemory, src, dest->resource.size);
- }
- GL_EXTCALL(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB));
- checkGLcall("glUnmapBufferARB");
- }
+ buffer_get_sysmem(dest);
}
/* Get a pointer into the destination vbo(create one if none exists) and
ERR("Cannot change the device window yet\n");
}
if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil_buffer) {
- WARN("Auto depth stencil enabled, but no auto depth stencil present, returning WINED3DERR_INVALIDCALL\n");
- return WINED3DERR_INVALIDCALL;
+ HRESULT hrc;
+
+ TRACE("Creating the depth stencil buffer\n");
+
+ hrc = IWineD3DDeviceParent_CreateDepthStencilSurface(This->device_parent,
+ This->parent,
+ pPresentationParameters->BackBufferWidth,
+ pPresentationParameters->BackBufferHeight,
+ pPresentationParameters->AutoDepthStencilFormat,
+ pPresentationParameters->MultiSampleType,
+ pPresentationParameters->MultiSampleQuality,
+ FALSE,
+ &This->auto_depth_stencil_buffer);
+
+ if (FAILED(hrc)) {
+ ERR("Failed to create the depth stencil buffer\n");
+ IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
+ return WINED3DERR_INVALIDCALL;
+ }
}
/* Reset the depth stencil */
{"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
{"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
{"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
+ {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 },
+ {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX, 0 },
/* EXT */
{"GL_EXT_blend_color", EXT_BLEND_COLOR, 0 },
if(!wined3d_fake_gl_context_foreign && glCtx) {
TRACE_(d3d_caps)("destroying fake GL context\n");
pwglMakeCurrent(NULL, NULL);
- //ros hack, this line does destire the real icd interface in windows and reactos
- // pwglDeleteContext(glCtx);
+ //pwglDeleteContext(glCtx);
}
if(wined3d_fake_gl_context_hdc)
ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
gl_info->supported[NV_TEXTURE_SHADER3] = FALSE;
}
-
+ if(gl_info->supported[NV_HALF_FLOAT]) {
+ /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float */
+ gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
+ }
+ if(gl_info->supported[ARB_POINT_SPRITE]) {
+ gl_info->max_point_sprite_units = gl_info->max_textures;
+ } else {
+ gl_info->max_point_sprite_units = 0;
+ }
}
checkGLcall("extension detection\n");
/* Floating point formats */
case WINED3DFMT_R16_FLOAT:
+ case WINED3DFMT_R16G16_FLOAT:
case WINED3DFMT_R16G16B16A16_FLOAT:
if(GL_SUPPORT(ARB_TEXTURE_FLOAT) && GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
TRACE_(d3d_caps)("[OK]\n");
return FALSE;
case WINED3DFMT_R32_FLOAT:
+ case WINED3DFMT_R32G32_FLOAT:
case WINED3DFMT_R32G32B32A32_FLOAT:
if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
TRACE_(d3d_caps)("[OK]\n");
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
- case WINED3DFMT_R16G16_FLOAT:
- case WINED3DFMT_R32G32_FLOAT:
- if(GL_SUPPORT(ARB_TEXTURE_RG)) {
- TRACE_(d3d_caps)("[OK]\n");
- return TRUE;
- }
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
-
/* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
* instancing. To query if the card supports instancing CheckDeviceFormat with the special format
* MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
WINED3DDTCAPS_UBYTE4N |
WINED3DDTCAPS_SHORT2N |
WINED3DDTCAPS_SHORT4N;
- if (GL_SUPPORT(NV_HALF_FLOAT)) {
+ if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX)) {
pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
WINED3DDTCAPS_FLOAT16_4;
}
return IUnknown_Release(volumeParent);
}
-static BOOL implementation_is_apple(const WineD3D_GL_Info *gl_info)
+static BOOL match_apple(const WineD3D_GL_Info *gl_info)
{
/* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
* the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
while(glGetError());
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
checkGLcall("Specifying the PBO test texture\n");
/* TODO: Add information about legacy ATI hardware, Intel and other cards */
};
-static void fixup_extensions(WineD3D_GL_Info *gl_info) {
- unsigned int i;
- BOOL apple = implementation_is_apple(gl_info);
+static BOOL match_ati_r300_to_500(const WineD3D_GL_Info *gl_info) {
+ if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_9500) return TRUE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_X700) return TRUE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_X1600) return TRUE;
+ return FALSE;
+}
- if(apple) {
- /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
- * used it falls back to software. While the compiler can detect if the shader uses all declared
- * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
- * using relative addressing falls back to software.
- *
- * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
- */
- if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
- FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
- } else {
- TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
- gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
- gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
+static BOOL match_geforce5(const WineD3D_GL_Info *gl_info) {
+ if(gl_info->gl_vendor == VENDOR_NVIDIA) {
+ if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
+ return TRUE;
}
+ }
+ return FALSE;
+}
- /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
- * with fixed function fragment processing. Ideally this flag should be detected with a test shader
- * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
- * do not like vertex shaders in feedback mode and return an error, even though it should be valid
- * according to the spec.
- *
- * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
- * makes the shader slower and eats instruction slots which should be available to the d3d app.
- *
- * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
- * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
- * this workaround is activated on cards that do not need it, it won't break things, just affect
- * performance negatively.
- */
- if(gl_info->gl_vendor == VENDOR_INTEL ||
- (gl_info->gl_vendor == VENDOR_ATI && gl_info->gl_card != CARD_ATI_RADEON_X1600)) {
- TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
- gl_info->set_texcoord_w = TRUE;
- }
+static BOOL match_apple_intel(const WineD3D_GL_Info *gl_info) {
+ return gl_info->gl_vendor == VENDOR_INTEL && match_apple(gl_info);
+}
+
+static BOOL match_apple_nonr500ati(const WineD3D_GL_Info *gl_info) {
+ if(!match_apple(gl_info)) return FALSE;
+ if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_X1600) return FALSE;
+ return TRUE;
+}
+
+static BOOL match_fglrx(const WineD3D_GL_Info *gl_info) {
+ if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+ if(match_apple(gl_info)) return FALSE;
+ if(strstr(gl_info->gl_renderer, "DRI")) return FALSE; /* Filter out Mesa DRI drivers */
+ return TRUE;
+}
+
+static void quirk_arb_constants(WineD3D_GL_Info *gl_info) {
+ TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL\n", gl_info->vs_arb_constantsF);
+ gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
+ TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL\n", gl_info->ps_arb_constantsF);
+ gl_info->ps_glsl_constantsF = gl_info->ps_arb_constantsF;
+}
+
+static void quirk_apple_glsl_constants(WineD3D_GL_Info *gl_info) {
+ quirk_arb_constants(gl_info);
+ /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
+ * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
+ * allow 48 different offsets or other helper immediate values
+ */
+ TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use\n");
+ gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
+}
+
+/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
+ * on more than one texture unit. This means that the d3d9 visual point size test will cause a
+ * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
+ * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
+ * most games, but avoids the crash
+ *
+ * A more sophisticated way would be to find all units that need texture coordinates and enable
+ * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
+ * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
+ *
+ * Note that disabling the extension entirely does not gain predictability because there is no point
+ * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension.
+ */
+static void quirk_one_point_sprite(WineD3D_GL_Info *gl_info) {
+ if(gl_info->supported[ARB_POINT_SPRITE]) {
+ TRACE("Limiting point sprites to one texture unit\n");
+ gl_info->max_point_sprite_units = 1;
}
+}
+
+static void quirk_ati_dx9(WineD3D_GL_Info *gl_info) {
+ quirk_arb_constants(gl_info);
/* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
* these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
* has this extension promoted to core. The extension loading code sets this extension supported
* due to that, so this code works on fglrx as well.
*/
- if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
- if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
- gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500 ||
- gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
- TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
- gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
- gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
- }
- }
+ TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
+ gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+ gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
+
+ /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
+ * it is generally more efficient. Reserve just 8 constants
+ */
+ TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use\n");
+ gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
+}
+static void quirk_no_np2(WineD3D_GL_Info *gl_info) {
/* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
* doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
* This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
* post-processing effects in the game "Max Payne 2").
* The behaviour can be verified through a simple test app attached in bugreport #14724.
*/
- if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_NVIDIA) {
- if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
- TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing\n");
- gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
- gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
- }
+ TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing\n");
+ gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+ gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
+}
+
+static void quirk_texcoord_w(WineD3D_GL_Info *gl_info) {
+ /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
+ * with fixed function fragment processing. Ideally this flag should be detected with a test shader
+ * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
+ * do not like vertex shaders in feedback mode and return an error, even though it should be valid
+ * according to the spec.
+ *
+ * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
+ * makes the shader slower and eats instruction slots which should be available to the d3d app.
+ *
+ * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
+ * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
+ * this workaround is activated on cards that do not need it, it won't break things, just affect
+ * performance negatively.
+ */
+ TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
+ gl_info->set_texcoord_w = TRUE;
+}
+
+struct driver_quirk quirk_table[] = {
+ {
+ match_ati_r300_to_500,
+ quirk_ati_dx9,
+ "ATI GLSL constant and normalized texrect quirk"
+ },
+ /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
+ * used it falls back to software. While the compiler can detect if the shader uses all declared
+ * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
+ * using relative addressing falls back to software.
+ *
+ * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
+ */
+ {
+ match_apple,
+ quirk_apple_glsl_constants,
+ "Apple GLSL uniform override"
+ },
+ {
+ match_geforce5,
+ quirk_no_np2,
+ "Geforce 5 NP2 disable"
+ },
+ {
+ match_apple_intel,
+ quirk_texcoord_w,
+ "Init texcoord .w for Apple Intel GPU driver"
+ },
+ {
+ match_apple_nonr500ati,
+ quirk_texcoord_w,
+ "Init texcoord .w for Apple ATI >= r600 GPU driver"
+ },
+ {
+ match_fglrx,
+ quirk_one_point_sprite,
+ "Fglrx point sprite crash workaround"
+ }
+};
+
+static void fixup_extensions(WineD3D_GL_Info *gl_info) {
+ unsigned int i;
+
+ for(i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); i++) {
+ if(!quirk_table[i].match(gl_info)) continue;
+ TRACE_(d3d_caps)("Applying driver quirk \"%s\"\n", quirk_table[i].description);
+ quirk_table[i].apply(gl_info);
}
/* Find out if PBOs work as they are supposed to */
multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
if (GL_SUPPORT(NV_HALF_FLOAT))
{
+ /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
} else {
* byte float according to the IEEE standard
*/
if (GL_SUPPORT(NV_HALF_FLOAT)) {
+ /* Not supported by GL_ARB_half_float_vertex */
GL_EXTCALL(glVertexAttrib2hvNV(index, ptr));
} else {
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
break;
case WINED3DFMT_R16G16B16A16_FLOAT:
if (GL_SUPPORT(NV_HALF_FLOAT)) {
+ /* Not supported by GL_ARB_half_float_vertex */
GL_EXTCALL(glVertexAttrib4hvNV(index, ptr));
} else {
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
* Copyright 2006 Jason Green
* Copyright 2006-2007 Henri Verbeet
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#define WINED3D_GLSL_SAMPLE_PROJECTED 0x1
#define WINED3D_GLSL_SAMPLE_RECT 0x2
#define WINED3D_GLSL_SAMPLE_LOD 0x4
+#define WINED3D_GLSL_SAMPLE_GRAD 0x8
typedef struct {
char reg_name[150];
typedef struct {
char reg_name[150];
- char param_str[100];
+ char param_str[200];
} glsl_src_param_t;
typedef struct {
const local_constant *lconst;
/* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
- if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.reg_maps.shader_version) == 1
- && shader_is_pshader_version(This->baseShader.reg_maps.shader_version))
+ if (This->baseShader.reg_maps.shader_version.major == 1
+ && shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type))
walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
else
walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
GLint tmp_loc;
unsigned int i;
char tmp_name[8];
- char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
+ char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
const char* prefix = is_pshader? "PB":"VB";
struct list* ptr;
if (-1 != prog->np2Fixup_location[i]) {
const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
if (!tex) {
- FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n");
+ FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
continue;
} else {
const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]};
prog->vuniformF_locations, &priv->vconst_heap, priv->stack, constant_version);
/* Load DirectX 9 integer constants/uniforms for vertex shader */
- if(vshader->baseShader.uses_int_consts) {
- shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations,
- stateBlock->vertexShaderConstantI, stateBlock->changed.vertexShaderConstantsI);
- }
+ shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations, stateBlock->vertexShaderConstantI,
+ stateBlock->changed.vertexShaderConstantsI & vshader->baseShader.reg_maps.integer_constants);
/* Load DirectX 9 boolean constants/uniforms for vertex shader */
- if(vshader->baseShader.uses_bool_consts) {
- shader_glsl_load_constantsB(vshader, gl_info, programId,
- stateBlock->vertexShaderConstantB, stateBlock->changed.vertexShaderConstantsB);
- }
+ shader_glsl_load_constantsB(vshader, gl_info, programId, stateBlock->vertexShaderConstantB,
+ stateBlock->changed.vertexShaderConstantsB & vshader->baseShader.reg_maps.boolean_constants);
/* Upload the position fixup params */
GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0]));
prog->puniformF_locations, &priv->pconst_heap, priv->stack, constant_version);
/* Load DirectX 9 integer constants/uniforms for pixel shader */
- if(pshader->baseShader.uses_int_consts) {
- shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations,
- stateBlock->pixelShaderConstantI, stateBlock->changed.pixelShaderConstantsI);
- }
+ shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations, stateBlock->pixelShaderConstantI,
+ stateBlock->changed.pixelShaderConstantsI & pshader->baseShader.reg_maps.integer_constants);
/* Load DirectX 9 boolean constants/uniforms for pixel shader */
- if(pshader->baseShader.uses_bool_consts) {
- shader_glsl_load_constantsB(pshader, gl_info, programId,
- stateBlock->pixelShaderConstantB, stateBlock->changed.pixelShaderConstantsB);
- }
+ shader_glsl_load_constantsB(pshader, gl_info, programId, stateBlock->pixelShaderConstantB,
+ stateBlock->changed.pixelShaderConstantsB & pshader->baseShader.reg_maps.boolean_constants);
/* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
* It can't be 0 for a valid texbem instruction.
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
- DWORD shader_version = reg_maps->shader_version;
unsigned int i, extra_constants_needed = 0;
const local_constant *lconst;
/* There are some minor differences between pixel and vertex shaders */
- char pshader = shader_is_pshader_version(shader_version);
+ char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
char prefix = pshader ? 'P' : 'V';
/* Prototype the subroutines */
/* Declare the constants (aka uniforms) */
if (This->baseShader.limits.constant_float > 0) {
unsigned max_constantsF;
+ /* Unless the shader uses indirect addressing, always declare the maximum array size and ignore that we need some
+ * uniforms privately. E.g. if GL supports 256 uniforms, and we need 2 for the pos fixup and immediate values, still
+ * declare VC[256]. If the shader needs more uniforms than we have it won't work in any case. If it uses less, the
+ * compiler will figure out which uniforms are really used and strip them out. This allows a shader to use c255 on
+ * a dx9 card, as long as it doesn't also use all the other constants.
+ *
+ * If the shader uses indirect addressing the compiler must assume that all declared uniforms are used. In this case,
+ * declare only the amount that we're assured to have.
+ *
+ * Thus we run into problems in these two cases:
+ * 1) The shader really uses more uniforms than supported
+ * 2) The shader uses indirect addressing, less constants than supported, but uses a constant index > #supported consts
+ */
if(pshader) {
- max_constantsF = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
- max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
+ /* No indirect addressing here */
+ max_constantsF = GL_LIMITS(pshader_constantsF);
} else {
- /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
- max_constantsF = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
- max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
+ if(This->baseShader.reg_maps.usesrelconstF) {
+ /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix).
+ * Subtract another uniform for immediate values, which have to be loaded via uniform by the driver as well.
+ * The shader code only uses 0.5, 2.0, 1.0, 128 and -128 in vertex shader code, so one vec4 should be enough
+ * (Unfortunately the Nvidia driver doesn't store 128 and -128 in one float
+ */
+ max_constantsF = GL_LIMITS(vshader_constantsF) - 3;
+ max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants);
+ /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly,
+ * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but
+ * for now take this into account when calculating the number of available constants
+ */
+ max_constantsF -= count_bits(This->baseShader.reg_maps.boolean_constants);
+ /* Set by driver quirks in directx.c */
+ max_constantsF -= GLINFO_LOCATION.reserved_glsl_constants;
+ } else {
+ max_constantsF = GL_LIMITS(vshader_constantsF);
+ }
}
+ max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF);
}
- if (This->baseShader.limits.constant_int > 0)
+ /* Always declare the full set of constants, the compiler can remove the unused ones because d3d doesn't(yet)
+ * support indirect int and bool constant addressing. This avoids problems if the app uses e.g. i0 and i9.
+ */
+ if (This->baseShader.limits.constant_int > 0 && This->baseShader.reg_maps.integer_constants)
shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int);
- if (This->baseShader.limits.constant_bool > 0)
+ if (This->baseShader.limits.constant_bool > 0 && This->baseShader.reg_maps.boolean_constants)
shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, This->baseShader.limits.constant_bool);
if(!pshader) {
* out. The nvidia driver only does that if the parameter is inout instead of out, hence the
* inout.
*/
- if (shader_version >= WINED3DVS_VERSION(3, 0))
+ if (reg_maps->shader_version.major >= 3)
{
shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT);
} else {
/* Declare texture samplers */
for (i = 0; i < This->baseShader.limits.sampler; i++) {
- if (reg_maps->samplers[i]) {
-
- DWORD stype = reg_maps->samplers[i] & WINED3DSP_TEXTURETYPE_MASK;
- switch (stype) {
-
+ if (reg_maps->sampler_type[i])
+ {
+ switch (reg_maps->sampler_type[i])
+ {
case WINED3DSTT_1D:
shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i);
break;
shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
}
- if(ps_args->np2_fixup & (1 << i)) {
+ if (pshader && ps_args->np2_fixup & (1 << i))
+ {
/* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
* while D3D has them in the (normalized) [0,1]x[0,1] range.
* samplerNP2Fixup stores texture dimensions and is updated through
break;
default:
shader_addline(buffer, "uniform unsupported_sampler %csampler%u;\n", prefix, i);
- FIXME("Unrecognized sampler type: %#x\n", stype);
+ FIXME("Unrecognized sampler type: %#x\n", reg_maps->sampler_type[i]);
break;
}
}
/* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
* helper function shader that is linked in at link time
*/
- if (pshader && shader_version >= WINED3DPS_VERSION(3, 0))
+ if (pshader && reg_maps->shader_version.major >= 3)
{
if (use_vs(device->stateBlock))
{
****************************************************************************/
/* Prototypes */
-static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins, const DWORD param,
- const DWORD addr_token, DWORD mask, glsl_src_param_t *src_param);
+static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_src_param *wined3d_src, DWORD mask, glsl_src_param_t *glsl_src);
/** Used for opcode modifiers - They multiply the result by the specified amount */
static const char * const shift_glsl_tab[] = {
};
/* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
-static void shader_glsl_gen_modifier (
- const DWORD instr,
- const char *in_reg,
- const char *in_regswizzle,
- char *out_str) {
-
+static void shader_glsl_gen_modifier(DWORD src_modifier, const char *in_reg, const char *in_regswizzle, char *out_str)
+{
out_str[0] = 0;
- switch (instr & WINED3DSP_SRCMOD_MASK) {
+ switch (src_modifier)
+ {
case WINED3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */
case WINED3DSPSM_DW:
case WINED3DSPSM_NONE:
sprintf(out_str, "-abs(%s%s)", in_reg, in_regswizzle);
break;
default:
- FIXME("Unhandled modifier %u\n", (instr & WINED3DSP_SRCMOD_MASK));
+ FIXME("Unhandled modifier %u\n", src_modifier);
sprintf(out_str, "%s%s", in_reg, in_regswizzle);
}
}
/** Writes the GLSL variable name that corresponds to the register that the
* DX opcode parameter is trying to access */
-static void shader_glsl_get_register_name(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx,
- BOOL rel_addr, const DWORD addr_token, char *register_name, BOOL *is_color,
- const struct wined3d_shader_instruction *ins)
+static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg,
+ char *register_name, BOOL *is_color, const struct wined3d_shader_instruction *ins)
{
/* oPos, oFog and oPts in D3D */
static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
- IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader;
+ IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
- DWORD shader_version = This->baseShader.reg_maps.shader_version;
- char pshader = shader_is_pshader_version(shader_version);
+ char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
*is_color = FALSE;
- switch (register_type)
+ switch (reg->type)
{
- case WINED3DSPR_TEMP:
- sprintf(register_name, "R%u", register_idx);
- break;
- case WINED3DSPR_INPUT:
- if (pshader) {
- /* Pixel shaders >= 3.0 */
- if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3)
+ case WINED3DSPR_TEMP:
+ sprintf(register_name, "R%u", reg->idx);
+ break;
+
+ case WINED3DSPR_INPUT:
+ /* vertex shaders */
+ if (!pshader)
+ {
+ if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg->idx)) *is_color = TRUE;
+ sprintf(register_name, "attrib%u", reg->idx);
+ break;
+ }
+
+ /* pixel shaders >= 3.0 */
+ if (This->baseShader.reg_maps.shader_version.major >= 3)
{
+ DWORD idx = ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg->idx];
DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
- if (rel_addr)
+ if (reg->rel_addr)
{
glsl_src_param_t rel_param;
- shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
+
+ shader_glsl_add_src_param(ins, reg->rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
/* Removing a + 0 would be an obvious optimization, but macos doesn't see the NOP
- * operation there
- */
- if (((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx])
+ * operation there */
+ if (idx)
{
- if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) {
- sprintf(register_name, "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])",
- rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count - 1,
- rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count,
- rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]);
- } else {
- sprintf(register_name, "IN[%s + %u]", rel_param.param_str,
- ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]);
+ if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count)
+ {
+ sprintf(register_name,
+ "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])",
+ rel_param.param_str, idx, in_count - 1, rel_param.param_str, idx, in_count,
+ rel_param.param_str, idx);
}
- } else {
- if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) {
+ else
+ {
+ sprintf(register_name, "IN[%s + %u]", rel_param.param_str, idx);
+ }
+ }
+ else
+ {
+ if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count)
+ {
sprintf(register_name, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])",
- rel_param.param_str, in_count - 1,
- rel_param.param_str, in_count,
+ rel_param.param_str, in_count - 1, rel_param.param_str, in_count,
rel_param.param_str);
- } else {
+ }
+ else
+ {
sprintf(register_name, "IN[%s]", rel_param.param_str);
}
}
- } else {
- DWORD idx = ((IWineD3DPixelShaderImpl *) This)->input_reg_map[register_idx];
- if (idx == in_count) {
- sprintf(register_name, "gl_Color");
- } else if (idx == in_count + 1) {
- sprintf(register_name, "gl_SecondaryColor");
- } else {
- sprintf(register_name, "IN[%u]", idx);
- }
}
- } else {
- if (register_idx == 0)
- strcpy(register_name, "gl_Color");
else
- strcpy(register_name, "gl_SecondaryColor");
+ {
+ if (idx == in_count) sprintf(register_name, "gl_Color");
+ else if (idx == in_count + 1) sprintf(register_name, "gl_SecondaryColor");
+ else sprintf(register_name, "IN[%u]", idx);
+ }
}
- } else {
- if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE;
- sprintf(register_name, "attrib%u", register_idx);
- }
- break;
- case WINED3DSPR_CONST:
- {
- const char prefix = pshader? 'P':'V';
+ else
+ {
+ if (reg->idx == 0) strcpy(register_name, "gl_Color");
+ else strcpy(register_name, "gl_SecondaryColor");
+ break;
+ }
+ break;
- /* Relative addressing */
- if (rel_addr)
- {
- /* Relative addressing on shaders 2.0+ have a relative address token,
- * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
- if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
- {
- glsl_src_param_t rel_param;
- shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
- if (register_idx)
- {
- sprintf(register_name, "%cC[%s + %u]", prefix, rel_param.param_str, register_idx);
- } else {
- sprintf(register_name, "%cC[%s]", prefix, rel_param.param_str);
- }
- } else {
- if (register_idx)
- {
- sprintf(register_name, "%cC[A0.x + %u]", prefix, register_idx);
- } else {
- sprintf(register_name, "%cC[A0.x]", prefix);
- }
- }
+ case WINED3DSPR_CONST:
+ {
+ const char prefix = pshader ? 'P' : 'V';
- } else {
- if (shader_constant_is_local(This, register_idx))
+ /* Relative addressing */
+ if (reg->rel_addr)
+ {
+ glsl_src_param_t rel_param;
+ shader_glsl_add_src_param(ins, reg->rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
+ if (reg->idx) sprintf(register_name, "%cC[%s + %u]", prefix, rel_param.param_str, reg->idx);
+ else sprintf(register_name, "%cC[%s]", prefix, rel_param.param_str);
+ }
+ else
+ {
+ if (shader_constant_is_local(This, reg->idx))
+ sprintf(register_name, "%cLC%u", prefix, reg->idx);
+ else
+ sprintf(register_name, "%cC[%u]", prefix, reg->idx);
+ }
+ }
+ break;
+
+ case WINED3DSPR_CONSTINT:
+ if (pshader) sprintf(register_name, "PI[%u]", reg->idx);
+ else sprintf(register_name, "VI[%u]", reg->idx);
+ break;
+
+ case WINED3DSPR_CONSTBOOL:
+ if (pshader) sprintf(register_name, "PB[%u]", reg->idx);
+ else sprintf(register_name, "VB[%u]", reg->idx);
+ break;
+
+ case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
+ if (pshader) sprintf(register_name, "T%u", reg->idx);
+ else sprintf(register_name, "A%u", reg->idx);
+ break;
+
+ case WINED3DSPR_LOOP:
+ sprintf(register_name, "aL%u", This->baseShader.cur_loop_regno - 1);
+ break;
+
+ case WINED3DSPR_SAMPLER:
+ if (pshader) sprintf(register_name, "Psampler%u", reg->idx);
+ else sprintf(register_name, "Vsampler%u", reg->idx);
+ break;
+
+ case WINED3DSPR_COLOROUT:
+ if (reg->idx >= GL_LIMITS(buffers))
+ WARN("Write to render target %u, only %d supported\n", reg->idx, 4);
+
+ if (GL_SUPPORT(ARB_DRAW_BUFFERS)) sprintf(register_name, "gl_FragData[%u]", reg->idx);
+ /* On older cards with GLSL support like the GeforceFX there's only one buffer. */
+ else sprintf(register_name, "gl_FragColor");
+ break;
+
+ case WINED3DSPR_RASTOUT:
+ sprintf(register_name, "%s", hwrastout_reg_names[reg->idx]);
+ break;
+
+ case WINED3DSPR_DEPTHOUT:
+ sprintf(register_name, "gl_FragDepth");
+ break;
+
+ case WINED3DSPR_ATTROUT:
+ if (reg->idx == 0) sprintf(register_name, "gl_FrontColor");
+ else sprintf(register_name, "gl_FrontSecondaryColor");
+ break;
+
+ case WINED3DSPR_TEXCRDOUT:
+ /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
+ if (This->baseShader.reg_maps.shader_version.major >= 3) sprintf(register_name, "OUT[%u]", reg->idx);
+ else sprintf(register_name, "gl_TexCoord[%u]", reg->idx);
+ break;
+
+ case WINED3DSPR_MISCTYPE:
+ if (reg->idx == 0)
{
- sprintf(register_name, "%cLC%u", prefix, register_idx);
- } else {
- sprintf(register_name, "%cC[%u]", prefix, register_idx);
+ /* vPos */
+ sprintf(register_name, "vpos");
}
- }
+ else if (reg->idx == 1)
+ {
+ /* Note that gl_FrontFacing is a bool, while vFace is
+ * a float for which the sign determines front/back */
+ sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)");
+ }
+ else
+ {
+ FIXME("Unhandled misctype register %d\n", reg->idx);
+ sprintf(register_name, "unrecognized_register");
+ }
+ break;
- break;
- }
- case WINED3DSPR_CONSTINT:
- if (pshader)
- sprintf(register_name, "PI[%u]", register_idx);
- else
- sprintf(register_name, "VI[%u]", register_idx);
- break;
- case WINED3DSPR_CONSTBOOL:
- if (pshader)
- sprintf(register_name, "PB[%u]", register_idx);
- else
- sprintf(register_name, "VB[%u]", register_idx);
- break;
- case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
- if (pshader) {
- sprintf(register_name, "T%u", register_idx);
- } else {
- sprintf(register_name, "A%u", register_idx);
- }
- break;
- case WINED3DSPR_LOOP:
- sprintf(register_name, "aL%u", This->baseShader.cur_loop_regno - 1);
- break;
- case WINED3DSPR_SAMPLER:
- if (pshader)
- sprintf(register_name, "Psampler%u", register_idx);
- else
- sprintf(register_name, "Vsampler%u", register_idx);
- break;
- case WINED3DSPR_COLOROUT:
- if (register_idx >= GL_LIMITS(buffers))
- WARN("Write to render target %u, only %d supported\n", register_idx, 4);
-
- if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
- sprintf(register_name, "gl_FragData[%u]", register_idx);
- } else { /* On older cards with GLSL support like the GeforceFX there's only one buffer. */
- sprintf(register_name, "gl_FragColor");
- }
- break;
- case WINED3DSPR_RASTOUT:
- sprintf(register_name, "%s", hwrastout_reg_names[register_idx]);
- break;
- case WINED3DSPR_DEPTHOUT:
- sprintf(register_name, "gl_FragDepth");
- break;
- case WINED3DSPR_ATTROUT:
- if (register_idx == 0)
- {
- sprintf(register_name, "gl_FrontColor");
- } else {
- sprintf(register_name, "gl_FrontSecondaryColor");
- }
- break;
- case WINED3DSPR_TEXCRDOUT:
- /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
- if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(register_name, "OUT[%u]", register_idx);
- else sprintf(register_name, "gl_TexCoord[%u]", register_idx);
- break;
- case WINED3DSPR_MISCTYPE:
- if (register_idx == 0)
- {
- /* vPos */
- sprintf(register_name, "vpos");
- }
- else if (register_idx == 1)
- {
- /* Note that gl_FrontFacing is a bool, while vFace is
- * a float for which the sign determines front/back
- */
- sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)");
- } else {
- FIXME("Unhandled misctype register %d\n", register_idx);
+ case WINED3DSPR_IMMCONST:
+ switch (reg->immconst_type)
+ {
+ case WINED3D_IMMCONST_FLOAT:
+ sprintf(register_name, "%.8e", *(float *)reg->immconst_data);
+ break;
+
+ case WINED3D_IMMCONST_FLOAT4:
+ sprintf(register_name, "vec4(%.8e, %.8e, %.8e, %.8e)",
+ *(float *)®->immconst_data[0], *(float *)®->immconst_data[1],
+ *(float *)®->immconst_data[2], *(float *)®->immconst_data[3]);
+ break;
+
+ default:
+ FIXME("Unhandled immconst type %#x\n", reg->immconst_type);
+ sprintf(register_name, "<unhandled_immconst_type %#x>", reg->immconst_type);
+ }
+ break;
+
+ default:
+ FIXME("Unhandled register name Type(%d)\n", reg->type);
sprintf(register_name, "unrecognized_register");
- }
- break;
- default:
- FIXME("Unhandled register name Type(%d)\n", register_type);
- sprintf(register_name, "unrecognized_register");
- break;
+ break;
}
}
{
DWORD mask = param->write_mask;
- if (shader_is_scalar(param->register_type, param->register_idx))
+ if (shader_is_scalar(¶m->reg))
{
mask = WINED3DSP_WRITEMASK_0;
*write_mask = '\0';
return size;
}
-static void shader_glsl_get_swizzle(const DWORD param, BOOL fixup, DWORD mask, char *swizzle_str) {
+static void shader_glsl_swizzle_to_str(const DWORD swizzle, BOOL fixup, DWORD mask, char *str)
+{
/* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
* but addressed as "rgba". To fix this we need to swap the register's x
* and z components. */
- DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
- char *ptr = swizzle_str;
- if (!shader_is_scalar(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK))
- {
- *ptr++ = '.';
- /* swizzle bits fields: wwzzyyxx */
- if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = swizzle_chars[swizzle & 0x03];
- if (mask & WINED3DSP_WRITEMASK_1) *ptr++ = swizzle_chars[(swizzle >> 2) & 0x03];
- if (mask & WINED3DSP_WRITEMASK_2) *ptr++ = swizzle_chars[(swizzle >> 4) & 0x03];
- if (mask & WINED3DSP_WRITEMASK_3) *ptr++ = swizzle_chars[(swizzle >> 6) & 0x03];
- }
+ *str++ = '.';
+ /* swizzle bits fields: wwzzyyxx */
+ if (mask & WINED3DSP_WRITEMASK_0) *str++ = swizzle_chars[swizzle & 0x03];
+ if (mask & WINED3DSP_WRITEMASK_1) *str++ = swizzle_chars[(swizzle >> 2) & 0x03];
+ if (mask & WINED3DSP_WRITEMASK_2) *str++ = swizzle_chars[(swizzle >> 4) & 0x03];
+ if (mask & WINED3DSP_WRITEMASK_3) *str++ = swizzle_chars[(swizzle >> 6) & 0x03];
+ *str = '\0';
+}
- *ptr = '\0';
+static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param,
+ BOOL fixup, DWORD mask, char *swizzle_str)
+{
+ if (shader_is_scalar(¶m->reg))
+ *swizzle_str = '\0';
+ else
+ shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str);
}
/* From a given parameter token, generate the corresponding GLSL string.
* Also, return the actual register name and swizzle in case the
* caller needs this information as well. */
static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
- const DWORD param, const DWORD addr_token, DWORD mask, glsl_src_param_t *src_param)
+ const struct wined3d_shader_src_param *wined3d_src, DWORD mask, glsl_src_param_t *glsl_src)
{
BOOL is_color = FALSE;
char swizzle_str[6];
- src_param->reg_name[0] = '\0';
- src_param->param_str[0] = '\0';
+ glsl_src->reg_name[0] = '\0';
+ glsl_src->param_str[0] = '\0';
swizzle_str[0] = '\0';
- shader_glsl_get_register_name(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK,
- param & WINED3DSHADER_ADDRMODE_RELATIVE, addr_token, src_param->reg_name, &is_color, ins);
-
- shader_glsl_get_swizzle(param, is_color, mask, swizzle_str);
- shader_glsl_gen_modifier(param, src_param->reg_name, swizzle_str, src_param->param_str);
+ shader_glsl_get_register_name(&wined3d_src->reg, glsl_src->reg_name, &is_color, ins);
+ shader_glsl_get_swizzle(wined3d_src, is_color, mask, swizzle_str);
+ shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, glsl_src->param_str);
}
/* From a given parameter token, generate the corresponding GLSL string.
glsl_dst->mask_str[0] = '\0';
glsl_dst->reg_name[0] = '\0';
- shader_glsl_get_register_name(wined3d_dst->register_type, wined3d_dst->register_idx,
- wined3d_dst->has_rel_addr, wined3d_dst->addr_token, glsl_dst->reg_name, &is_color, ins);
+ shader_glsl_get_register_name(&wined3d_dst->reg, glsl_dst->reg_name, &is_color, ins);
return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str);
}
}
/** Process GLSL instruction modifiers */
-void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins)
{
glsl_dst_param_t dst_param;
DWORD modifiers;
if (modifiers & WINED3DSPDM_SATURATE)
{
/* _SAT means to clamp the value of the register to between 0 and 1 */
- shader_addline(ins->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name,
+ shader_addline(ins->ctx->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name,
dst_param.mask_str, dst_param.reg_name, dst_param.mask_str);
}
}
}
-static inline const char *shader_get_comp_op(DWORD flags)
+static inline const char *shader_get_comp_op(DWORD op)
{
- DWORD op = (flags & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
switch (op) {
case COMPARISON_GT: return ">";
case COMPARISON_EQ: return "==";
BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
+ BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD;
/* Note that there's no such thing as a projected cube texture. */
switch(sampler_type) {
case WINED3DSTT_1D:
if(lod) {
sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
+ } else if(grad) {
+ sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
} else {
sample_function->name = projected ? "texture1DProj" : "texture1D";
}
if(texrect) {
if(lod) {
sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
+ } else if(grad) {
+ /* What good are texrect grad functions? I don't know, but GL_EXT_gpu_shader4 defines them.
+ * There is no GL_ARB_shader_texture_lod spec yet, so I don't know if they're defined there
+ */
+ sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB";
} else {
sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
}
} else {
if(lod) {
sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
+ } else if(grad) {
+ sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
} else {
sample_function->name = projected ? "texture2DProj" : "texture2D";
}
case WINED3DSTT_CUBE:
if(lod) {
sample_function->name = "textureCubeLod";
+ } else if(grad) {
+ sample_function->name = "textureCubeGradARB";
} else {
sample_function->name = "textureCube";
}
case WINED3DSTT_VOLUME:
if(lod) {
sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
+ } else if(grad) {
+ sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
} else {
sample_function->name = projected ? "texture3DProj" : "texture3D";
}
if (mask_size > 1)
{
- shader_addline(ins->buffer, "%s%s = vec%u(%s);\n",
+ shader_addline(ins->ctx->buffer, "%s%s = vec%u(%s);\n",
dst_param.reg_name, dst_param.mask_str, mask_size, arguments);
}
else
{
- shader_addline(ins->buffer, "%s%s = %s;\n", dst_param.reg_name, dst_param.mask_str, arguments);
+ shader_addline(ins->ctx->buffer, "%s%s = %s;\n", dst_param.reg_name, dst_param.mask_str, arguments);
}
}
-static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
+static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
DWORD sampler, const glsl_sample_function_t *sample_function, DWORD swizzle,
+ const char *dx, const char *dy,
const char *bias, const char *coord_reg_fmt, ...)
{
const char *sampler_base;
BOOL np2_fixup = FALSE;
va_list args;
- shader_glsl_get_swizzle(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
+ shader_glsl_swizzle_to_str(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
- if (shader_is_pshader_version(ins->reg_maps->shader_version))
+ if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
fixup = This->cur_args->color_fixup[sampler];
sampler_base = "Psampler";
fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */
}
- shader_glsl_append_dst(ins->buffer, ins);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
- shader_addline(ins->buffer, "%s(%s%u, ", sample_function->name, sampler_base, sampler);
+ shader_addline(ins->ctx->buffer, "%s(%s%u, ", sample_function->name, sampler_base, sampler);
va_start(args, coord_reg_fmt);
- shader_vaddline(ins->buffer, coord_reg_fmt, args);
+ shader_vaddline(ins->ctx->buffer, coord_reg_fmt, args);
va_end(args);
if(bias) {
- shader_addline(ins->buffer, ", %s)%s);\n", bias, dst_swizzle);
+ shader_addline(ins->ctx->buffer, ", %s)%s);\n", bias, dst_swizzle);
} else {
if (np2_fixup) {
- shader_addline(ins->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, dst_swizzle);
+ shader_addline(ins->ctx->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, dst_swizzle);
+ } else if(dx && dy) {
+ shader_addline(ins->ctx->buffer, ", %s, %s)%s);\n", dx, dy, dst_swizzle);
} else {
- shader_addline(ins->buffer, ")%s);\n", dst_swizzle);
+ shader_addline(ins->ctx->buffer, ")%s);\n", dst_swizzle);
}
}
/* Generate GLSL arithmetic functions (dst = src1 + src2) */
static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
DWORD write_mask;
}
write_mask = shader_glsl_append_dst(buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
shader_addline(buffer, "%s %c %s);\n", src0_param.param_str, op, src1_param.param_str);
}
/* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
DWORD write_mask;
write_mask = shader_glsl_append_dst(buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
/* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
* shader versions WINED3DSIO_MOVA is used for this. */
- if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1
- && !shader_is_pshader_version(ins->reg_maps->shader_version)
- && ins->dst[0].register_type == WINED3DSPR_ADDR))
+ if (ins->ctx->reg_maps->shader_version.major == 1
+ && !shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)
+ && ins->dst[0].reg.type == WINED3DSPR_ADDR)
{
/* This is a simple floor() */
unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
/* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
static void shader_glsl_dot(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
DWORD dst_write_mask, src_write_mask;
src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
}
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_write_mask, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], src_write_mask, &src1_param);
if (dst_size > 1) {
shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
char dst_mask[6];
shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
- shader_glsl_append_dst(ins->buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_mask, &src1_param);
- shader_addline(ins->buffer, "cross(%s, %s)%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
+ shader_addline(ins->ctx->buffer, "cross(%s, %s)%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
}
/* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1)
* GLSL uses the value as-is. */
static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
DWORD dst_write_mask;
dst_write_mask = shader_glsl_append_dst(buffer, ins);
dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
if (dst_size > 1) {
shader_addline(buffer, "vec%d(pow(abs(%s), %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
* GLSL uses the value as-is. */
static void shader_glsl_log(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
DWORD dst_write_mask;
unsigned int dst_size;
dst_write_mask = shader_glsl_append_dst(buffer, ins);
dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
if (dst_size > 1) {
shader_addline(buffer, "vec%d(log2(abs(%s))));\n", dst_size, src0_param.param_str);
/* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src_param;
const char *instruction;
DWORD write_mask;
if (ins->src_count)
{
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
shader_addline(buffer, "%s", src_param.param_str);
for (i = 1; i < ins->src_count; ++i)
{
- shader_glsl_add_src_param(ins, ins->src[i], ins->src_addr[i], write_mask, &src_param);
+ shader_glsl_add_src_param(ins, &ins->src[i], write_mask, &src_param);
shader_addline(buffer, ", %s", src_param.param_str);
}
}
{
glsl_src_param_t src_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param);
- if (ins->reg_maps->shader_version < WINED3DPS_VERSION(2,0))
+ if (ins->ctx->reg_maps->shader_version.major < 2)
{
char dst_mask[6];
- shader_addline(ins->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
- shader_addline(ins->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str);
- shader_addline(ins->buffer, "tmp0.z = exp2(%s);\n", src_param.param_str);
- shader_addline(ins->buffer, "tmp0.w = 1.0;\n");
+ shader_addline(ins->ctx->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
+ shader_addline(ins->ctx->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str);
+ shader_addline(ins->ctx->buffer, "tmp0.z = exp2(%s);\n", src_param.param_str);
+ shader_addline(ins->ctx->buffer, "tmp0.w = 1.0;\n");
- shader_glsl_append_dst(ins->buffer, ins);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
- shader_addline(ins->buffer, "tmp0%s);\n", dst_mask);
+ shader_addline(ins->ctx->buffer, "tmp0%s);\n", dst_mask);
} else {
DWORD write_mask;
unsigned int mask_size;
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
mask_size = shader_glsl_get_write_mask_size(write_mask);
if (mask_size > 1) {
- shader_addline(ins->buffer, "vec%d(exp2(%s)));\n", mask_size, src_param.param_str);
+ shader_addline(ins->ctx->buffer, "vec%d(exp2(%s)));\n", mask_size, src_param.param_str);
} else {
- shader_addline(ins->buffer, "exp2(%s));\n", src_param.param_str);
+ shader_addline(ins->ctx->buffer, "exp2(%s));\n", src_param.param_str);
}
}
}
DWORD write_mask;
unsigned int mask_size;
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
mask_size = shader_glsl_get_write_mask_size(write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &src_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
if (mask_size > 1) {
- shader_addline(ins->buffer, "vec%d(1.0 / %s));\n", mask_size, src_param.param_str);
+ shader_addline(ins->ctx->buffer, "vec%d(1.0 / %s));\n", mask_size, src_param.param_str);
} else {
- shader_addline(ins->buffer, "1.0 / %s);\n", src_param.param_str);
+ shader_addline(ins->ctx->buffer, "1.0 / %s);\n", src_param.param_str);
}
}
static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
{
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src_param;
DWORD write_mask;
unsigned int mask_size;
write_mask = shader_glsl_append_dst(buffer, ins);
mask_size = shader_glsl_get_write_mask_size(write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &src_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
if (mask_size > 1) {
shader_addline(buffer, "vec%d(inversesqrt(%s)));\n", mask_size, src_param.param_str);
DWORD write_mask;
unsigned int mask_size;
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
mask_size = shader_glsl_get_write_mask_size(write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
if (mask_size > 1) {
const char *compare;
FIXME("Can't handle opcode %#x\n", ins->handler_idx);
}
- shader_addline(ins->buffer, "vec%d(%s(%s, %s)));\n", mask_size, compare,
+ shader_addline(ins->ctx->buffer, "vec%d(%s(%s, %s)));\n", mask_size, compare,
src0_param.param_str, src1_param.param_str);
} else {
switch(ins->handler_idx)
* issue. Playing with not() is not possible either because not() does not accept
* a scalar.
*/
- shader_addline(ins->buffer, "(%s < %s) ? 1.0 : 0.0);\n", src0_param.param_str, src1_param.param_str);
+ shader_addline(ins->ctx->buffer, "(%s < %s) ? 1.0 : 0.0);\n",
+ src0_param.param_str, src1_param.param_str);
break;
case WINED3DSIH_SGE:
/* Here we can use the step() function and safe a conditional */
- shader_addline(ins->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str);
break;
default:
FIXME("Can't handle opcode %#x\n", ins->handler_idx);
char mask_char[6];
BOOL temp_destination = FALSE;
- if (shader_is_scalar(shader_get_regtype(ins->src[0]), ins->src[0] & WINED3DSP_REGNUM_MASK))
+ if (shader_is_scalar(&ins->src[0].reg))
{
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
- shader_addline(ins->buffer, "%s >= 0.0 ? %s : %s);\n",
+ shader_addline(ins->ctx->buffer, "%s >= 0.0 ? %s : %s);\n",
src0_param.param_str, src1_param.param_str, src2_param.param_str);
} else {
- DWORD src0reg = ins->src[0] & WINED3DSP_REGNUM_MASK;
- DWORD src1reg = ins->src[1] & WINED3DSP_REGNUM_MASK;
- DWORD src2reg = ins->src[2] & WINED3DSP_REGNUM_MASK;
- DWORD src0regtype = shader_get_regtype(ins->src[0]);
- DWORD src1regtype = shader_get_regtype(ins->src[1]);
- DWORD src2regtype = shader_get_regtype(ins->src[2]);
- DWORD dstreg = ins->dst[0].register_idx;
- DWORD dstregtype = ins->dst[0].register_type;
DWORD dst_mask = ins->dst[0].write_mask;
struct wined3d_shader_dst_param dst = ins->dst[0];
write_mask = 0;
/* Find the destination channels which use the current source0 channel */
for (j=0; j<4; j++) {
- if (((ins->src[0] >> (WINED3DSP_SWIZZLE_SHIFT + 2 * j)) & 0x3) == i)
+ if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
{
write_mask |= WINED3DSP_WRITEMASK_0 << j;
cmp_channel = WINED3DSP_WRITEMASK_0 << j;
* The first lines may overwrite source parameters of the following lines.
* Deal with that by using a temporary destination register if needed
*/
- if ((src0reg == dstreg && src0regtype == dstregtype)
- || (src1reg == dstreg && src1regtype == dstregtype)
- || (src2reg == dstreg && src2regtype == dstregtype))
+ if ((ins->src[0].reg.idx == ins->dst[0].reg.idx
+ && ins->src[0].reg.type == ins->dst[0].reg.type)
+ || (ins->src[1].reg.idx == ins->dst[0].reg.idx
+ && ins->src[1].reg.type == ins->dst[0].reg.type)
+ || (ins->src[2].reg.idx == ins->dst[0].reg.idx
+ && ins->src[2].reg.type == ins->dst[0].reg.type))
{
write_mask = shader_glsl_get_write_mask(&dst, mask_char);
if (!write_mask) continue;
- shader_addline(ins->buffer, "tmp0%s = (", mask_char);
+ shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char);
temp_destination = TRUE;
} else {
- write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst);
+ write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst);
if (!write_mask) continue;
}
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], cmp_channel, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
- shader_addline(ins->buffer, "%s >= 0.0 ? %s : %s);\n",
+ shader_addline(ins->ctx->buffer, "%s >= 0.0 ? %s : %s);\n",
src0_param.param_str, src1_param.param_str, src2_param.param_str);
}
if(temp_destination) {
shader_glsl_get_write_mask(&ins->dst[0], mask_char);
- shader_glsl_append_dst(ins->buffer, ins);
- shader_addline(ins->buffer, "tmp0%s);\n", mask_char);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_addline(ins->ctx->buffer, "tmp0%s);\n", mask_char);
}
}
DWORD write_mask, cmp_channel = 0;
unsigned int i, j;
DWORD dst_mask;
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
- if (ins->reg_maps->shader_version < WINED3DPS_VERSION(1, 4))
+ if (shader_version < WINED3D_SHADER_VERSION(1, 4))
{
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
/* Fun: The D3DSI_COISSUE flag changes the semantic of the cnd instruction for < 1.4 shaders */
if (ins->coissue)
{
- shader_addline(ins->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
+ shader_addline(ins->ctx->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
} else {
- shader_addline(ins->buffer, "%s > 0.5 ? %s : %s);\n",
+ shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
src0_param.param_str, src1_param.param_str, src2_param.param_str);
}
return;
write_mask = 0;
/* Find the destination channels which use the current source0 channel */
for (j=0; j<4; j++) {
- if (((ins->src[0] >> (WINED3DSP_SWIZZLE_SHIFT + 2 * j)) & 0x3) == i)
+ if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
{
write_mask |= WINED3DSP_WRITEMASK_0 << j;
cmp_channel = WINED3DSP_WRITEMASK_0 << j;
}
dst.write_mask = dst_mask & write_mask;
- write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst);
+ write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst);
if (!write_mask) continue;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], cmp_channel, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
- shader_addline(ins->buffer, "%s > 0.5 ? %s : %s);\n",
+ shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
src0_param.param_str, src1_param.param_str, src2_param.param_str);
}
}
glsl_src_param_t src2_param;
DWORD write_mask;
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
- shader_addline(ins->buffer, "(%s * %s) + %s);\n",
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+ shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n",
src0_param.param_str, src1_param.param_str, src2_param.param_str);
}
{
int i;
int nComponents = 0;
- struct wined3d_shader_dst_param tmp_dst = {0};
+ struct wined3d_shader_dst_param tmp_dst = {{0}};
+ struct wined3d_shader_src_param tmp_src[2] = {{{0}}};
struct wined3d_shader_instruction tmp_ins;
memset(&tmp_ins, 0, sizeof(tmp_ins));
/* Set constants for the temporary argument */
- tmp_ins.shader = ins->shader;
- tmp_ins.buffer = ins->buffer;
- tmp_ins.src[0] = ins->src[0];
- tmp_ins.src_addr[0] = ins->src_addr[0];
- tmp_ins.src_addr[1] = ins->src_addr[1];
- tmp_ins.reg_maps = ins->reg_maps;
+ tmp_ins.ctx = ins->ctx;
tmp_ins.dst_count = 1;
tmp_ins.dst = &tmp_dst;
tmp_ins.src_count = 2;
+ tmp_ins.src = tmp_src;
switch(ins->handler_idx)
{
}
tmp_dst = ins->dst[0];
+ tmp_src[0] = ins->src[0];
+ tmp_src[1] = ins->src[1];
for (i = 0; i < nComponents; ++i)
{
tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
- tmp_ins.src[1] = ins->src[1] + i;
shader_glsl_dot(&tmp_ins);
+ ++tmp_src[1].reg.idx;
}
}
glsl_src_param_t src2_param;
DWORD write_mask;
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
- shader_addline(ins->buffer, "mix(%s, %s, %s));\n",
+ shader_addline(ins->ctx->buffer, "mix(%s, %s, %s));\n",
src2_param.param_str, src1_param.param_str, src0_param.param_str);
}
glsl_src_param_t src3_param;
char dst_mask[6];
- shader_glsl_append_dst(ins->buffer, ins);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &src3_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src3_param);
/* The sdk specifies the instruction like this
* dst.x = 1.0;
* which sets dst.z to 0. If y > 0, but x = 0.0, we get pow(y * 0.0, power), which results in 0 too.
* if both x and y are > 0, we get pow(y * 1.0, power), as it is supposed to
*/
- shader_addline(ins->buffer,
+ shader_addline(ins->ctx->buffer,
"vec4(1.0, max(%s, 0.0), pow(max(0.0, %s) * step(0.0, %s), clamp(%s, -128.0, 128.0)), 1.0)%s);\n",
src0_param.param_str, src1_param.param_str, src0_param.param_str, src3_param.param_str, dst_mask);
}
glsl_src_param_t src1w_param;
char dst_mask[6];
- shader_glsl_append_dst(ins->buffer, ins);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src0y_param);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &src0z_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_1, &src1y_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_3, &src1w_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src0y_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &src0z_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_1, &src1y_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_3, &src1w_param);
- shader_addline(ins->buffer, "vec4(1.0, %s * %s, %s, %s))%s;\n",
+ shader_addline(ins->ctx->buffer, "vec4(1.0, %s * %s, %s, %s))%s;\n",
src0y_param.param_str, src1y_param.param_str, src0z_param.param_str, src1w_param.param_str, dst_mask);
}
glsl_src_param_t src0_param;
DWORD write_mask;
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
switch (write_mask) {
case WINED3DSP_WRITEMASK_0:
- shader_addline(ins->buffer, "cos(%s));\n", src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "cos(%s));\n", src0_param.param_str);
break;
case WINED3DSP_WRITEMASK_1:
- shader_addline(ins->buffer, "sin(%s));\n", src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "sin(%s));\n", src0_param.param_str);
break;
case (WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1):
- shader_addline(ins->buffer, "vec2(cos(%s), sin(%s)));\n", src0_param.param_str, src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "vec2(cos(%s), sin(%s)));\n", src0_param.param_str, src0_param.param_str);
break;
default:
static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
{
glsl_src_param_t src1_param;
- IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
- DWORD regtype = shader_get_regtype(ins->src[1]);
- DWORD reg = ins->src[1] & WINED3DSP_REGNUM_MASK;
+ IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
const DWORD *control_values = NULL;
const local_constant *constant;
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
/* Try to hardcode the loop control parameters if possible. Direct3D 9 class hardware doesn't support real
* varying indexing, but Microsoft designed this feature for Shader model 2.x+. If the loop control is
* known at compile time, the GLSL compiler can unroll the loop, and replace indirect addressing with direct
* addressing.
*/
- if(regtype == WINED3DSPR_CONSTINT) {
+ if (ins->src[1].reg.type == WINED3DSPR_CONSTINT)
+ {
LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry) {
- if(constant->idx == reg) {
+ if (constant->idx == ins->src[1].reg.idx)
+ {
control_values = constant->value;
break;
}
if(control_values) {
if(control_values[2] > 0) {
- shader_addline(ins->buffer, "for (aL%u = %d; aL%u < (%d * %d + %d); aL%u += %d) {\n",
+ shader_addline(ins->ctx->buffer, "for (aL%u = %d; aL%u < (%d * %d + %d); aL%u += %d) {\n",
shader->baseShader.cur_loop_depth, control_values[1],
shader->baseShader.cur_loop_depth, control_values[0], control_values[2], control_values[1],
shader->baseShader.cur_loop_depth, control_values[2]);
} else if(control_values[2] == 0) {
- shader_addline(ins->buffer, "for (aL%u = %d, tmpInt%u = 0; tmpInt%u < %d; tmpInt%u++) {\n",
+ shader_addline(ins->ctx->buffer, "for (aL%u = %d, tmpInt%u = 0; tmpInt%u < %d; tmpInt%u++) {\n",
shader->baseShader.cur_loop_depth, control_values[1], shader->baseShader.cur_loop_depth,
shader->baseShader.cur_loop_depth, control_values[0],
shader->baseShader.cur_loop_depth);
} else {
- shader_addline(ins->buffer, "for (aL%u = %d; aL%u > (%d * %d + %d); aL%u += %d) {\n",
+ shader_addline(ins->ctx->buffer, "for (aL%u = %d; aL%u > (%d * %d + %d); aL%u += %d) {\n",
shader->baseShader.cur_loop_depth, control_values[1],
shader->baseShader.cur_loop_depth, control_values[0], control_values[2], control_values[1],
shader->baseShader.cur_loop_depth, control_values[2]);
}
} else {
- shader_addline(ins->buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z) {\n",
+ shader_addline(ins->ctx->buffer,
+ "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z) {\n",
shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno,
src1_param.reg_name, shader->baseShader.cur_loop_depth, src1_param.reg_name,
shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno, src1_param.reg_name);
static void shader_glsl_end(const struct wined3d_shader_instruction *ins)
{
- IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
+ IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
- shader_addline(ins->buffer, "}\n");
+ shader_addline(ins->ctx->buffer, "}\n");
if (ins->handler_idx == WINED3DSIH_ENDLOOP)
{
static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
{
- IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
+ IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
glsl_src_param_t src0_param;
+ const DWORD *control_values = NULL;
+ const local_constant *constant;
+
+ /* Try to hardcode local values to help the GLSL compiler to unroll and optimize the loop */
+ if (ins->src[0].reg.type == WINED3DSPR_CONSTINT)
+ {
+ LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry)
+ {
+ if (constant->idx == ins->src[0].reg.idx)
+ {
+ control_values = constant->value;
+ break;
+ }
+ }
+ }
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_addline(ins->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n",
- shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth,
- src0_param.param_str, shader->baseShader.cur_loop_depth);
+ if(control_values) {
+ shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %d; tmpInt%d++) {\n",
+ shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth,
+ control_values[0], shader->baseShader.cur_loop_depth);
+ } else {
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n",
+ shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth,
+ src0_param.param_str, shader->baseShader.cur_loop_depth);
+ }
shader->baseShader.cur_loop_depth++;
}
{
glsl_src_param_t src0_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_addline(ins->buffer, "if (%s) {\n", src0_param.param_str);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_addline(ins->ctx->buffer, "if (%s) {\n", src0_param.param_str);
}
static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
- shader_addline(ins->buffer, "if (%s %s %s) {\n",
+ shader_addline(ins->ctx->buffer, "if (%s %s %s) {\n",
src0_param.param_str, shader_get_comp_op(ins->flags), src1_param.param_str);
}
static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
{
- shader_addline(ins->buffer, "} else {\n");
+ shader_addline(ins->ctx->buffer, "} else {\n");
}
static void shader_glsl_break(const struct wined3d_shader_instruction *ins)
{
- shader_addline(ins->buffer, "break;\n");
+ shader_addline(ins->ctx->buffer, "break;\n");
}
/* FIXME: According to MSDN the compare is done per component. */
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
- shader_addline(ins->buffer, "if (%s %s %s) break;\n",
+ shader_addline(ins->ctx->buffer, "if (%s %s %s) break;\n",
src0_param.param_str, shader_get_comp_op(ins->flags), src1_param.param_str);
}
static void shader_glsl_label(const struct wined3d_shader_instruction *ins)
{
-
- DWORD snum = (ins->src[0]) & WINED3DSP_REGNUM_MASK;
- shader_addline(ins->buffer, "}\n");
- shader_addline(ins->buffer, "void subroutine%u () {\n", snum);
+ shader_addline(ins->ctx->buffer, "}\n");
+ shader_addline(ins->ctx->buffer, "void subroutine%u () {\n", ins->src[0].reg.idx);
}
static void shader_glsl_call(const struct wined3d_shader_instruction *ins)
{
- DWORD snum = (ins->src[0]) & WINED3DSP_REGNUM_MASK;
- shader_addline(ins->buffer, "subroutine%u();\n", snum);
+ shader_addline(ins->ctx->buffer, "subroutine%u();\n", ins->src[0].reg.idx);
}
static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
{
glsl_src_param_t src1_param;
- DWORD snum = (ins->src[0]) & WINED3DSP_REGNUM_MASK;
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
- shader_addline(ins->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, snum);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
+ shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, ins->src[0].reg.idx);
}
/*********************************************
********************************************/
static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
- DWORD shader_version = ins->reg_maps->shader_version;
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
glsl_sample_function_t sample_function;
DWORD sample_flags = 0;
- DWORD sampler_type;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
DWORD sampler_idx;
DWORD mask = 0, swizzle;
/* 1.0-1.4: Use destination register as sampler source.
* 2.0+: Use provided sampler source. */
- if (shader_version < WINED3DPS_VERSION(2,0)) sampler_idx = ins->dst[0].register_idx;
- else sampler_idx = ins->src[1] & WINED3DSP_REGNUM_MASK;
- sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ if (shader_version < WINED3D_SHADER_VERSION(2,0)) sampler_idx = ins->dst[0].reg.idx;
+ else sampler_idx = ins->src[1].reg.idx;
+ sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
- if (shader_version < WINED3DPS_VERSION(1,4))
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
{
DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
}
}
}
- else if (shader_version < WINED3DPS_VERSION(2,0))
+ else if (shader_version < WINED3D_SHADER_VERSION(2,0))
{
- DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK;
+ DWORD src_mod = ins->src[0].modifiers;
if (src_mod == WINED3DSPSM_DZ) {
sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
mask |= sample_function.coord_mask;
- if (shader_version < WINED3DPS_VERSION(2,0)) swizzle = WINED3DVS_NOSWIZZLE;
- else swizzle = ins->src[1] & WINED3DSP_SWIZZLE_MASK;
+ if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
+ else swizzle = ins->src[1].swizzle;
/* 1.0-1.3: Use destination register as coordinate source.
1.4+: Use provided coordinate source register. */
- if (shader_version < WINED3DPS_VERSION(1,4))
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
{
char coord_mask[6];
shader_glsl_write_mask_to_str(mask, coord_mask);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
"T%u%s", sampler_idx, coord_mask);
} else {
glsl_src_param_t coord_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], mask, &coord_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], mask, &coord_param);
if (ins->flags & WINED3DSI_TEXLD_BIAS)
{
glsl_src_param_t bias;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &bias);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, bias.param_str,
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
"%s", coord_param.param_str);
} else {
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
"%s", coord_param.param_str);
}
}
}
+static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
+{
+ IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
+ IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+ const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
+ glsl_sample_function_t sample_function;
+ glsl_src_param_t coord_param, dx_param, dy_param;
+ DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
+ DWORD sampler_type;
+ DWORD sampler_idx;
+ DWORD swizzle = ins->src[1].swizzle;
+
+ if(!GL_SUPPORT(ARB_SHADER_TEXTURE_LOD)) {
+ FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
+ return pshader_glsl_tex(ins);
+ }
+
+ sampler_idx = ins->src[1].reg.idx;
+ sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
+ if(deviceImpl->stateBlock->textures[sampler_idx] &&
+ IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
+ sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
+ }
+
+ shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param);
+ shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param);
+
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, NULL,
+ "%s", coord_param.param_str);
+}
+
static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
{
- IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader;
+ IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param, lod_param;
DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
DWORD sampler_type;
DWORD sampler_idx;
- DWORD swizzle = ins->src[1] & WINED3DSP_SWIZZLE_MASK;
+ DWORD swizzle = ins->src[1].swizzle;
- sampler_idx = ins->src[1] & WINED3DSP_REGNUM_MASK;
- sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ sampler_idx = ins->src[1].reg.idx;
+ sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
if(deviceImpl->stateBlock->textures[sampler_idx] &&
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
}
shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], sample_function.coord_mask, &coord_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
- if (shader_is_pshader_version(ins->reg_maps->shader_version))
+ if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
{
/* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
* However, they seem to work just fine in fragment shaders as well. */
WARN("Using %s in fragment shader.\n", sample_function.name);
}
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, lod_param.param_str,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str,
"%s", coord_param.param_str);
}
static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
{
/* FIXME: Make this work for more than just 2D textures */
- SHADER_BUFFER *buffer = ins->buffer;
- DWORD write_mask = shader_glsl_append_dst(ins->buffer, ins);
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
+ DWORD write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
- if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
+ if (!(ins->ctx->reg_maps->shader_version.major == 1 && ins->ctx->reg_maps->shader_version.minor == 4))
{
char dst_mask[6];
shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n",
- ins->dst[0].register_idx, dst_mask);
+ ins->dst[0].reg.idx, dst_mask);
} else {
- DWORD reg = ins->src[0] & WINED3DSP_REGNUM_MASK;
- DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK;
+ DWORD reg = ins->src[0].reg.idx;
+ DWORD src_mod = ins->src[0].modifiers;
char dst_swizzle[6];
- shader_glsl_get_swizzle(ins->src[0], FALSE, write_mask, dst_swizzle);
+ shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
if (src_mod == WINED3DSPSM_DZ) {
glsl_src_param_t div_param;
unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &div_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &div_param);
if (mask_size > 1) {
shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
} else if (src_mod == WINED3DSPSM_DW) {
glsl_src_param_t div_param;
unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &div_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &div_param);
if (mask_size > 1) {
shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
{
glsl_src_param_t src0_param;
glsl_sample_function_t sample_function;
- DWORD sampler_idx = ins->dst[0].register_idx;
+ DWORD sampler_idx = ins->dst[0].reg.idx;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
UINT mask_size;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
/* Do I have to take care about the projected bit? I don't think so, since the dp3 returns only one
* scalar, and projected sampling would require 4.
switch(mask_size)
{
case 1:
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
break;
case 2:
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
break;
case 3:
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
break;
static void pshader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
{
glsl_src_param_t src0_param;
- DWORD dstreg = ins->dst[0].register_idx;
+ DWORD dstreg = ins->dst[0].reg.idx;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
DWORD dst_mask;
unsigned int mask_size;
- dst_mask = shader_glsl_append_dst(ins->buffer, ins);
+ dst_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
mask_size = shader_glsl_get_write_mask_size(dst_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
if (mask_size > 1) {
- shader_addline(ins->buffer, "vec%d(dot(T%u.xyz, %s)));\n", mask_size, dstreg, src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "vec%d(dot(T%u.xyz, %s)));\n", mask_size, dstreg, src0_param.param_str);
} else {
- shader_addline(ins->buffer, "dot(T%u.xyz, %s));\n", dstreg, src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "dot(T%u.xyz, %s));\n", dstreg, src0_param.param_str);
}
}
* too is irrelevant, since if x = 0, any y value < 1.0 (and > 1.0 is not allowed) results in a result
* >= 1.0 or < 0.0
*/
- shader_addline(ins->buffer, "gl_FragDepth = clamp((%s.x / min(%s.y, 1.0)), 0.0, 1.0);\n",
+ shader_addline(ins->ctx->buffer, "gl_FragDepth = clamp((%s.x / min(%s.y, 1.0)), 0.0, 1.0);\n",
dst_param.reg_name, dst_param.reg_name);
}
static void pshader_glsl_texm3x2depth(const struct wined3d_shader_instruction *ins)
{
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- DWORD dstreg = ins->dst[0].register_idx;
+ DWORD dstreg = ins->dst[0].reg.idx;
glsl_src_param_t src0_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
- shader_addline(ins->buffer, "tmp0.y = dot(T%u.xyz, %s);\n", dstreg, src0_param.param_str);
- shader_addline(ins->buffer, "gl_FragDepth = (tmp0.y == 0.0) ? 1.0 : clamp(tmp0.x / tmp0.y, 0.0, 1.0);\n");
+ shader_addline(ins->ctx->buffer, "tmp0.y = dot(T%u.xyz, %s);\n", dstreg, src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "gl_FragDepth = (tmp0.y == 0.0) ? 1.0 : clamp(tmp0.x / tmp0.y, 0.0, 1.0);\n");
}
/** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL
static void pshader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
{
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
shader_addline(buffer, "tmp0.x = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
}
* Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
static void pshader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
glsl_src_param_t src0_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
shader_addline(buffer, "tmp0.%c = dot(T%u.xyz, %s);\n", 'x' + current_state->current_row, reg, src0_param.param_str);
current_state->texcoord_w[current_state->current_row++] = reg;
}
static void pshader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
{
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
- DWORD sampler_type = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
glsl_sample_function_t sample_function;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xy");
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
}
/** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
{
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
glsl_src_param_t src0_param;
- DWORD reg = ins->dst[0].register_idx;
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ DWORD reg = ins->dst[0].reg.idx;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
- DWORD sampler_type = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
glsl_sample_function_t sample_function;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
- shader_addline(ins->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
current_state->current_row = 0;
}
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
glsl_src_param_t src0_param;
char dst_mask[6];
- DWORD reg = ins->dst[0].register_idx;
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ DWORD reg = ins->dst[0].reg.idx;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
- shader_glsl_append_dst(ins->buffer, ins);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
- shader_addline(ins->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
+ shader_addline(ins->ctx->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
current_state->current_row = 0;
}
* Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->shader;
- DWORD reg = ins->dst[0].register_idx;
+ IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+ DWORD reg = ins->dst[0].reg.idx;
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
- SHADER_BUFFER *buffer = ins->buffer;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
- DWORD stype = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+ WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg];
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
glsl_sample_function_t sample_function;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
/* Perform the last matrix multiply operation */
shader_addline(buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
shader_glsl_get_sample_function(stype, 0, &sample_function);
/* Sample the texture */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
current_state->current_row = 0;
}
* Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->shader;
- DWORD reg = ins->dst[0].register_idx;
- SHADER_BUFFER *buffer = ins->buffer;
+ IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+ DWORD reg = ins->dst[0].reg.idx;
+ SHADER_BUFFER *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
glsl_src_param_t src0_param;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
- DWORD sampler_type = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
glsl_sample_function_t sample_function;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
/* Perform the last matrix multiply operation */
shader_addline(buffer, "tmp0.z = dot(vec3(T%u), vec3(%s));\n", reg, src0_param.param_str);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
current_state->current_row = 0;
}
*/
static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
{
- IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+ IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param;
- DWORD sampler_type;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
DWORD sampler_idx;
DWORD mask;
DWORD flags;
char coord_mask[6];
- sampler_idx = ins->dst[0].register_idx;
+ sampler_idx = ins->dst[0].reg.idx;
flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
- sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
mask = sample_function.coord_mask;
case WINED3DTTFF_DISABLE: div_mask = WINED3DSP_WRITEMASK_3; break;
}
shader_glsl_write_mask_to_str(div_mask, coord_div_mask);
- shader_addline(ins->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
+ shader_addline(ins->ctx->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
}
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0],
- WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
coord_param.param_str, coord_mask);
glsl_src_param_t luminance_param;
glsl_dst_param_t dst_param;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &luminance_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &luminance_param);
shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
- shader_addline(ins->buffer, "%s%s *= (%s * luminancescale%d + luminanceoffset%d);\n",
+ shader_addline(ins->ctx->buffer, "%s%s *= (%s * luminancescale%d + luminanceoffset%d);\n",
dst_param.reg_name, dst_param.mask_str,
luminance_param.param_str, sampler_idx, sampler_idx);
}
static void pshader_glsl_bem(const struct wined3d_shader_instruction *ins)
{
glsl_src_param_t src0_param, src1_param;
- DWORD sampler_idx = ins->dst[0].register_idx;
+ DWORD sampler_idx = ins->dst[0].reg.idx;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0],
- WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1],
- WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
- shader_glsl_append_dst(ins->buffer, ins);
- shader_addline(ins->buffer, "%s + bumpenvmat%d * %s);\n",
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_addline(ins->ctx->buffer, "%s + bumpenvmat%d * %s);\n",
src0_param.param_str, sampler_idx, src1_param.param_str);
}
static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
{
glsl_src_param_t src0_param;
- DWORD sampler_idx = ins->dst[0].register_idx;
- DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ DWORD sampler_idx = ins->dst[0].reg.idx;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
glsl_sample_function_t sample_function;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"%s.wx", src0_param.reg_name);
}
static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
{
glsl_src_param_t src0_param;
- DWORD sampler_idx = ins->dst[0].register_idx;
- DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ DWORD sampler_idx = ins->dst[0].reg.idx;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
glsl_sample_function_t sample_function;
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"%s.yz", src0_param.reg_name);
}
static void pshader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
{
glsl_src_param_t src0_param;
- DWORD sampler_idx = ins->dst[0].register_idx;
- DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+ DWORD sampler_idx = ins->dst[0].reg.idx;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
glsl_sample_function_t sample_function;
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], sample_function.coord_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"%s", src0_param.param_str);
}
/* The argument is a destination parameter, and no writemasks are allowed */
shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
- if ((ins->reg_maps->shader_version >= WINED3DPS_VERSION(2,0)))
+ if (ins->ctx->reg_maps->shader_version.major >= 2)
{
/* 2.0 shaders compare all 4 components in texkill */
- shader_addline(ins->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
+ shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
} else {
/* 1.X shaders only compare the first 3 components, probably due to the nature of the texkill
* instruction as a tex* instruction, and phase, which kills all a / w components. Even if all
* 4 components are defined, only the first 3 are used
*/
- shader_addline(ins->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
+ shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
}
}
DWORD write_mask;
unsigned int mask_size;
- write_mask = shader_glsl_append_dst(ins->buffer, ins);
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
mask_size = shader_glsl_get_write_mask_size(write_mask);
- shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0],
- WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
- shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1],
- WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
- shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2],
- WINED3DSP_WRITEMASK_0, &src2_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &src2_param);
if (mask_size > 1) {
- shader_addline(ins->buffer, "vec%d(dot(%s, %s) + %s));\n",
+ shader_addline(ins->ctx->buffer, "vec%d(dot(%s, %s) + %s));\n",
mask_size, src0_param.param_str, src1_param.param_str, src2_param.param_str);
} else {
- shader_addline(ins->buffer, "dot(%s, %s) + %s);\n",
+ shader_addline(ins->ctx->buffer, "dot(%s, %s) + %s);\n",
src0_param.param_str, src1_param.param_str, src2_param.param_str);
}
}
IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader;
IWineD3DDeviceImpl *device;
- DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.reg_maps.shader_version);
- DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.reg_maps.shader_version) : 0;
+ DWORD vs_major = vs->baseShader.reg_maps.shader_version.major;
+ DWORD ps_major = ps ? ps->baseShader.reg_maps.shader_version.major : 0;
unsigned int i;
SHADER_BUFFER buffer;
DWORD usage, usage_idx, writemask;
checkGLcall("Find glsl program uniform locations");
if (pshader
- && WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version) >= 3
+ && ((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version.major >= 3
&& ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4)
{
TRACE("Shader %d needs vertex color clamping disabled\n", programId);
/* Note: Do not use QueryInterface here to find out which shader type this is because this code
* can be called from IWineD3DBaseShader::Release
*/
- char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
+ char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
if(pshader) {
ps = (IWineD3DPixelShaderImpl *) This;
return FALSE;
}
-static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
+static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface,
+ SHADER_BUFFER *buffer, const struct ps_compile_args *args)
+{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
shader_addline(buffer, "#extension GL_ARB_draw_buffers : enable\n");
}
+ if(GL_SUPPORT(ARB_SHADER_TEXTURE_LOD) && reg_maps->usestexldd) {
+ shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
+ }
if (GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
/* The spec says that it doesn't have to be explicitly enabled, but the nvidia
* drivers write a warning if we don't do so
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, args);
/* Pack 3.0 inputs */
- if (reg_maps->shader_version >= WINED3DPS_VERSION(3,0) && args->vp_mode != vertexshader) {
+ if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
+ {
pshader_glsl_input_pack(iface, buffer, This->semantics_in, reg_maps, args->vp_mode);
}
/* Base Shader Body */
- shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
+ shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
- if (reg_maps->shader_version < WINED3DPS_VERSION(2,0))
+ if (reg_maps->shader_version.major < 2)
{
/* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
if(GL_SUPPORT(ARB_DRAW_BUFFERS))
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
* -1/(e-s) and e/(e-s) respectively.
*/
- if(reg_maps->shader_version < WINED3DPS_VERSION(3,0)) {
+ if (reg_maps->shader_version.major < 3)
+ {
switch(args->fog) {
case FOG_OFF: break;
case FOG_LINEAR:
return shader_obj;
}
-static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
+static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface,
+ SHADER_BUFFER *buffer, const struct vs_compile_args *args)
+{
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
/* Base Shader Body */
- shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
+ shader_generate_main((IWineD3DBaseShader*)This, buffer, reg_maps, function);
/* Unpack 3.0 outputs */
- if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n");
+ if (reg_maps->shader_version.major >= 3) shader_addline(buffer, "order_ps_input(OUT);\n");
else shader_addline(buffer, "order_ps_input();\n");
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
else
pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (pCaps->VertexShaderVersion >> 8) & 0xff, pCaps->VertexShaderVersion & 0xff);
- /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
- pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
+ pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
/* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
* In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
else
pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
- /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
- * In theory the texbem instruction may need one more shader constant too. But lets assume
- * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
- * and lets not take away a uniform needlessly from all other shaders.
- */
- pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
+ pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF);
/* FIXME: The following line is card dependent. -8.0 to 8.0 is the
* Direct3D minimum requirement.
/* WINED3DSIH_TEXDP3 */ pshader_glsl_texdp3,
/* WINED3DSIH_TEXDP3TEX */ pshader_glsl_texdp3tex,
/* WINED3DSIH_TEXKILL */ pshader_glsl_texkill,
- /* WINED3DSIH_TEXLDD */ NULL,
+ /* WINED3DSIH_TEXLDD */ shader_glsl_texldd,
/* WINED3DSIH_TEXLDL */ shader_glsl_texldl,
/* WINED3DSIH_TEXM3x2DEPTH */ pshader_glsl_texm3x2depth,
/* WINED3DSIH_TEXM3x2PAD */ pshader_glsl_texm3x2pad,
shader_glsl_generate_vshader,
shader_glsl_get_caps,
shader_glsl_color_fixup_supported,
+ shader_glsl_add_instruction_modifiers,
};
return WINED3D_OK;
}
-CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
- /* Arithmetic */
- {WINED3DSIO_NOP, "nop", 0, 0, WINED3DSIH_NOP, 0, 0 },
- {WINED3DSIO_MOV, "mov", 1, 2, WINED3DSIH_MOV, 0, 0 },
- {WINED3DSIO_ADD, "add", 1, 3, WINED3DSIH_ADD, 0, 0 },
- {WINED3DSIO_SUB, "sub", 1, 3, WINED3DSIH_SUB, 0, 0 },
- {WINED3DSIO_MAD, "mad", 1, 4, WINED3DSIH_MAD, 0, 0 },
- {WINED3DSIO_MUL, "mul", 1, 3, WINED3DSIH_MUL, 0, 0 },
- {WINED3DSIO_RCP, "rcp", 1, 2, WINED3DSIH_RCP, 0, 0 },
- {WINED3DSIO_RSQ, "rsq", 1, 2, WINED3DSIH_RSQ, 0, 0 },
- {WINED3DSIO_DP3, "dp3", 1, 3, WINED3DSIH_DP3, 0, 0 },
- {WINED3DSIO_DP4, "dp4", 1, 3, WINED3DSIH_DP4, 0, 0 },
- {WINED3DSIO_MIN, "min", 1, 3, WINED3DSIH_MIN, 0, 0 },
- {WINED3DSIO_MAX, "max", 1, 3, WINED3DSIH_MAX, 0, 0 },
- {WINED3DSIO_SLT, "slt", 1, 3, WINED3DSIH_SLT, 0, 0 },
- {WINED3DSIO_SGE, "sge", 1, 3, WINED3DSIH_SGE, 0, 0 },
- {WINED3DSIO_ABS, "abs", 1, 2, WINED3DSIH_ABS, 0, 0 },
- {WINED3DSIO_EXP, "exp", 1, 2, WINED3DSIH_EXP, 0, 0 },
- {WINED3DSIO_LOG, "log", 1, 2, WINED3DSIH_LOG, 0, 0 },
- {WINED3DSIO_EXPP, "expp", 1, 2, WINED3DSIH_EXPP, 0, 0 },
- {WINED3DSIO_LOGP, "logp", 1, 2, WINED3DSIH_LOGP, 0, 0 },
- {WINED3DSIO_DST, "dst", 1, 3, WINED3DSIH_DST, 0, 0 },
- {WINED3DSIO_LRP, "lrp", 1, 4, WINED3DSIH_LRP, 0, 0 },
- {WINED3DSIO_FRC, "frc", 1, 2, WINED3DSIH_FRC, 0, 0 },
- {WINED3DSIO_CND, "cnd", 1, 4, WINED3DSIH_CND, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)},
- {WINED3DSIO_CMP, "cmp", 1, 4, WINED3DSIH_CMP, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)},
- {WINED3DSIO_POW, "pow", 1, 3, WINED3DSIH_POW, 0, 0 },
- {WINED3DSIO_CRS, "crs", 1, 3, WINED3DSIH_CRS, 0, 0 },
- {WINED3DSIO_NRM, "nrm", 1, 2, WINED3DSIH_NRM, 0, 0 },
- {WINED3DSIO_SINCOS, "sincos", 1, 4, WINED3DSIH_SINCOS, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
- {WINED3DSIO_SINCOS, "sincos", 1, 2, WINED3DSIH_SINCOS, WINED3DPS_VERSION(3,0), -1 },
- {WINED3DSIO_DP2ADD, "dp2add", 1, 4, WINED3DSIH_DP2ADD, WINED3DPS_VERSION(2,0), -1 },
- /* Matrix */
- {WINED3DSIO_M4x4, "m4x4", 1, 3, WINED3DSIH_M4x4, 0, 0 },
- {WINED3DSIO_M4x3, "m4x3", 1, 3, WINED3DSIH_M4x3, 0, 0 },
- {WINED3DSIO_M3x4, "m3x4", 1, 3, WINED3DSIH_M3x4, 0, 0 },
- {WINED3DSIO_M3x3, "m3x3", 1, 3, WINED3DSIH_M3x3, 0, 0 },
- {WINED3DSIO_M3x2, "m3x2", 1, 3, WINED3DSIH_M3x2, 0, 0 },
- /* Register declarations */
- {WINED3DSIO_DCL, "dcl", 0, 2, WINED3DSIH_DCL, 0, 0 },
- /* Flow control - requires GLSL or software shaders */
- {WINED3DSIO_REP , "rep", 0, 1, WINED3DSIH_REP, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_ENDREP, "endrep", 0, 0, WINED3DSIH_ENDREP, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_IF, "if", 0, 1, WINED3DSIH_IF, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_IFC, "ifc", 0, 2, WINED3DSIH_IFC, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_ELSE, "else", 0, 0, WINED3DSIH_ELSE, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_ENDIF, "endif", 0, 0, WINED3DSIH_ENDIF, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_BREAK, "break", 0, 0, WINED3DSIH_BREAK, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_BREAKC, "breakc", 0, 2, WINED3DSIH_BREAKC, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_BREAKP, "breakp", 0, 1, WINED3DSIH_BREAKP, 0, 0 },
- {WINED3DSIO_CALL, "call", 0, 1, WINED3DSIH_CALL, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_CALLNZ, "callnz", 0, 2, WINED3DSIH_CALLNZ, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_LOOP, "loop", 0, 2, WINED3DSIH_LOOP, WINED3DPS_VERSION(3,0), -1 },
- {WINED3DSIO_RET, "ret", 0, 0, WINED3DSIH_RET, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_ENDLOOP, "endloop", 0, 0, WINED3DSIH_ENDLOOP, WINED3DPS_VERSION(3,0), -1 },
- {WINED3DSIO_LABEL, "label", 0, 1, WINED3DSIH_LABEL, WINED3DPS_VERSION(2,1), -1 },
- /* Constant definitions */
- {WINED3DSIO_DEF, "def", 1, 5, WINED3DSIH_DEF, 0, 0 },
- {WINED3DSIO_DEFB, "defb", 1, 2, WINED3DSIH_DEFB, 0, 0 },
- {WINED3DSIO_DEFI, "defi", 1, 5, WINED3DSIH_DEFI, 0, 0 },
- /* Texture */
- {WINED3DSIO_TEXCOORD, "texcoord", 1, 1, WINED3DSIH_TEXCOORD, 0, WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXCOORD, "texcrd", 1, 2, WINED3DSIH_TEXCOORD, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
- {WINED3DSIO_TEXKILL, "texkill", 1, 1, WINED3DSIH_TEXKILL, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
- {WINED3DSIO_TEX, "tex", 1, 1, WINED3DSIH_TEX, 0, WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEX, "texld", 1, 2, WINED3DSIH_TEX, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
- {WINED3DSIO_TEX, "texld", 1, 3, WINED3DSIH_TEX, WINED3DPS_VERSION(2,0), -1 },
- {WINED3DSIO_TEXBEM, "texbem", 1, 2, WINED3DSIH_TEXBEM, 0, WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXBEML, "texbeml", 1, 2, WINED3DSIH_TEXBEML, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXREG2AR, "texreg2ar", 1, 2, WINED3DSIH_TEXREG2AR, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXREG2GB, "texreg2gb", 1, 2, WINED3DSIH_TEXREG2GB, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXREG2RGB, "texreg2rgb", 1, 2, WINED3DSIH_TEXREG2RGB, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x2PAD, "texm3x2pad", 1, 2, WINED3DSIH_TEXM3x2PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x2TEX, "texm3x2tex", 1, 2, WINED3DSIH_TEXM3x2TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x3PAD, "texm3x3pad", 1, 2, WINED3DSIH_TEXM3x3PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x3DIFF, "texm3x3diff", 1, 2, WINED3DSIH_TEXM3x3DIFF, WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)},
- {WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", 1, 3, WINED3DSIH_TEXM3x3SPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x3TEX, "texm3x3tex", 1, 2, WINED3DSIH_TEXM3x3TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXDP3TEX, "texdp3tex", 1, 2, WINED3DSIH_TEXDP3TEX, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXDP3, "texdp3", 1, 2, WINED3DSIH_TEXDP3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXM3x3, "texm3x3", 1, 2, WINED3DSIH_TEXM3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
- {WINED3DSIO_TEXDEPTH, "texdepth", 1, 1, WINED3DSIH_TEXDEPTH, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
- {WINED3DSIO_BEM, "bem", 1, 3, WINED3DSIH_BEM, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
- {WINED3DSIO_DSX, "dsx", 1, 2, WINED3DSIH_DSX, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_DSY, "dsy", 1, 2, WINED3DSIH_DSY, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_TEXLDD, "texldd", 1, 5, WINED3DSIH_TEXLDD, WINED3DPS_VERSION(2,1), -1 },
- {WINED3DSIO_SETP, "setp", 1, 3, WINED3DSIH_SETP, 0, 0 },
- {WINED3DSIO_TEXLDL, "texldl", 1, 3, WINED3DSIH_TEXLDL, WINED3DPS_VERSION(3,0), -1 },
- {WINED3DSIO_PHASE, "phase", 0, 0, WINED3DSIH_PHASE, 0, 0 },
- {0, NULL, 0, 0, 0, 0, 0 }
-};
+static void pshader_set_limits(IWineD3DPixelShaderImpl *This)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(This->baseShader.reg_maps.shader_version.major,
+ This->baseShader.reg_maps.shader_version.minor);
-static void pshader_set_limits(
- IWineD3DPixelShaderImpl *This) {
-
- This->baseShader.limits.attributes = 0;
- This->baseShader.limits.address = 0;
- This->baseShader.limits.packed_output = 0;
-
- switch (This->baseShader.reg_maps.shader_version)
- {
- case WINED3DPS_VERSION(1,0):
- case WINED3DPS_VERSION(1,1):
- case WINED3DPS_VERSION(1,2):
- case WINED3DPS_VERSION(1,3):
- This->baseShader.limits.temporary = 2;
- This->baseShader.limits.constant_float = 8;
- This->baseShader.limits.constant_int = 0;
- This->baseShader.limits.constant_bool = 0;
- This->baseShader.limits.texcoord = 4;
- This->baseShader.limits.sampler = 4;
- This->baseShader.limits.packed_input = 0;
- This->baseShader.limits.label = 0;
- break;
-
- case WINED3DPS_VERSION(1,4):
- This->baseShader.limits.temporary = 6;
- This->baseShader.limits.constant_float = 8;
- This->baseShader.limits.constant_int = 0;
- This->baseShader.limits.constant_bool = 0;
- This->baseShader.limits.texcoord = 6;
- This->baseShader.limits.sampler = 6;
- This->baseShader.limits.packed_input = 0;
- This->baseShader.limits.label = 0;
- break;
-
- /* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */
- case WINED3DPS_VERSION(2,0):
- This->baseShader.limits.temporary = 32;
- This->baseShader.limits.constant_float = 32;
- This->baseShader.limits.constant_int = 16;
- This->baseShader.limits.constant_bool = 16;
- This->baseShader.limits.texcoord = 8;
- This->baseShader.limits.sampler = 16;
- This->baseShader.limits.packed_input = 0;
- break;
-
- case WINED3DPS_VERSION(2,1):
- This->baseShader.limits.temporary = 32;
- This->baseShader.limits.constant_float = 32;
- This->baseShader.limits.constant_int = 16;
- This->baseShader.limits.constant_bool = 16;
- This->baseShader.limits.texcoord = 8;
- This->baseShader.limits.sampler = 16;
- This->baseShader.limits.packed_input = 0;
- This->baseShader.limits.label = 16;
- break;
-
- case WINED3DPS_VERSION(3,0):
- This->baseShader.limits.temporary = 32;
- This->baseShader.limits.constant_float = 224;
- This->baseShader.limits.constant_int = 16;
- This->baseShader.limits.constant_bool = 16;
- This->baseShader.limits.texcoord = 0;
- This->baseShader.limits.sampler = 16;
- This->baseShader.limits.packed_input = 12;
- This->baseShader.limits.label = 16; /* FIXME: 2048 */
- break;
-
- default: This->baseShader.limits.temporary = 32;
- This->baseShader.limits.constant_float = 32;
- This->baseShader.limits.constant_int = 16;
- This->baseShader.limits.constant_bool = 16;
- This->baseShader.limits.texcoord = 8;
- This->baseShader.limits.sampler = 16;
- This->baseShader.limits.packed_input = 0;
- This->baseShader.limits.label = 0;
- FIXME("Unrecognized pixel shader version %#x\n",
- This->baseShader.reg_maps.shader_version);
- }
-}
+ This->baseShader.limits.attributes = 0;
+ This->baseShader.limits.address = 0;
+ This->baseShader.limits.packed_output = 0;
-static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
+ switch (shader_version)
+ {
+ case WINED3D_SHADER_VERSION(1,0):
+ case WINED3D_SHADER_VERSION(1,1):
+ case WINED3D_SHADER_VERSION(1,2):
+ case WINED3D_SHADER_VERSION(1,3):
+ This->baseShader.limits.temporary = 2;
+ This->baseShader.limits.constant_float = 8;
+ This->baseShader.limits.constant_int = 0;
+ This->baseShader.limits.constant_bool = 0;
+ This->baseShader.limits.texcoord = 4;
+ This->baseShader.limits.sampler = 4;
+ This->baseShader.limits.packed_input = 0;
+ This->baseShader.limits.label = 0;
+ break;
+
+ case WINED3D_SHADER_VERSION(1,4):
+ This->baseShader.limits.temporary = 6;
+ This->baseShader.limits.constant_float = 8;
+ This->baseShader.limits.constant_int = 0;
+ This->baseShader.limits.constant_bool = 0;
+ This->baseShader.limits.texcoord = 6;
+ This->baseShader.limits.sampler = 6;
+ This->baseShader.limits.packed_input = 0;
+ This->baseShader.limits.label = 0;
+ break;
+
+ /* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */
+ case WINED3D_SHADER_VERSION(2,0):
+ This->baseShader.limits.temporary = 32;
+ This->baseShader.limits.constant_float = 32;
+ This->baseShader.limits.constant_int = 16;
+ This->baseShader.limits.constant_bool = 16;
+ This->baseShader.limits.texcoord = 8;
+ This->baseShader.limits.sampler = 16;
+ This->baseShader.limits.packed_input = 0;
+ break;
+
+ case WINED3D_SHADER_VERSION(2,1):
+ This->baseShader.limits.temporary = 32;
+ This->baseShader.limits.constant_float = 32;
+ This->baseShader.limits.constant_int = 16;
+ This->baseShader.limits.constant_bool = 16;
+ This->baseShader.limits.texcoord = 8;
+ This->baseShader.limits.sampler = 16;
+ This->baseShader.limits.packed_input = 0;
+ This->baseShader.limits.label = 16;
+ break;
+
+ case WINED3D_SHADER_VERSION(3,0):
+ This->baseShader.limits.temporary = 32;
+ This->baseShader.limits.constant_float = 224;
+ This->baseShader.limits.constant_int = 16;
+ This->baseShader.limits.constant_bool = 16;
+ This->baseShader.limits.texcoord = 0;
+ This->baseShader.limits.sampler = 16;
+ This->baseShader.limits.packed_input = 12;
+ This->baseShader.limits.label = 16; /* FIXME: 2048 */
+ break;
+
+ default:
+ This->baseShader.limits.temporary = 32;
+ This->baseShader.limits.constant_float = 32;
+ This->baseShader.limits.constant_int = 16;
+ This->baseShader.limits.constant_bool = 16;
+ This->baseShader.limits.texcoord = 8;
+ This->baseShader.limits.sampler = 16;
+ This->baseShader.limits.packed_input = 0;
+ This->baseShader.limits.label = 0;
+ FIXME("Unrecognized pixel shader version %u.%u\n",
+ This->baseShader.reg_maps.shader_version.major,
+ This->baseShader.reg_maps.shader_version.minor);
+ }
+}
+static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface,
+ const DWORD *pFunction, const struct wined3d_shader_signature *output_signature)
+{
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
- IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
unsigned int i, highest_reg_used = 0, num_regs_used = 0;
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+ const struct wined3d_shader_frontend *fe;
HRESULT hr;
TRACE("(%p) : pFunction %p\n", iface, pFunction);
+ fe = shader_select_frontend(*pFunction);
+ if (!fe)
+ {
+ FIXME("Unable to find frontend for shader.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ This->baseShader.frontend = fe;
+ This->baseShader.frontend_data = fe->shader_init(pFunction, output_signature);
+ if (!This->baseShader.frontend_data)
+ {
+ FIXME("Failed to initialize frontend.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
/* First pass: trace shader */
- if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
+ if (TRACE_ON(d3d_shader)) shader_trace_init(fe, This->baseShader.frontend_data, pFunction);
/* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF);
list_init(&This->baseShader.constantsI);
/* Second pass: figure out which registers are used, what the semantics are, etc.. */
- memset(reg_maps, 0, sizeof(shader_reg_maps));
- hr = shader_get_registers_used((IWineD3DBaseShader *)This, reg_maps, This->semantics_in, NULL, pFunction);
+ hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction,
+ GL_LIMITS(pshader_constantsF));
if (FAILED(hr)) return hr;
pshader_set_limits(This);
This->baseShader.load_local_constsF = FALSE;
- This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
-
TRACE("(%p) : Copying the function\n", This);
This->baseShader.function = HeapAlloc(GetProcessHeap(), 0, This->baseShader.functionLength);
static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures)
{
- DWORD shader_version = reg_maps->shader_version;
- DWORD *samplers = reg_maps->samplers;
+ WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type;
unsigned int i;
- if (WINED3DSHADER_VERSION_MAJOR(shader_version) != 1) return;
+ if (reg_maps->shader_version.major != 1) return;
for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
{
/* We don't sample from this sampler */
- if (!samplers[i]) continue;
+ if (!sampler_type[i]) continue;
if (!textures[i])
{
ERR("No texture bound to sampler %u, using 2D\n", i);
- samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+ sampler_type[i] = WINED3DSTT_2D;
continue;
}
case GL_TEXTURE_2D:
/* We have to select between texture rectangles and 2D textures later because 2.0 and
* 3.0 shaders only have WINED3DSTT_2D as well */
- samplers[i] = (1 << 31) | WINED3DSTT_2D;
+ sampler_type[i] = WINED3DSTT_2D;
break;
case GL_TEXTURE_3D:
- samplers[i] = (1 << 31) | WINED3DSTT_VOLUME;
+ sampler_type[i] = WINED3DSTT_VOLUME;
break;
case GL_TEXTURE_CUBE_MAP_ARB:
- samplers[i] = (1 << 31) | WINED3DSTT_CUBE;
+ sampler_type[i] = WINED3DSTT_CUBE;
break;
default:
FIXME("Unrecognized texture type %#x, using 2D\n",
IWineD3DBaseTexture_GetTextureDimensions(textures[i]));
- samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+ sampler_type[i] = WINED3DSTT_2D;
}
}
}
args->np2_fixup = 0;
for(i = 0; i < MAX_FRAGMENT_SAMPLERS; i++) {
- if(shader->baseShader.reg_maps.samplers[i] == 0) continue;
+ if (!shader->baseShader.reg_maps.sampler_type[i]) continue;
tex = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
if(!tex) {
args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
args->np2_fixup |= (1 << i);
}
}
- if (shader->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0))
+ if (shader->baseShader.reg_maps.shader_version.major >= 3)
{
if (((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.position_transformed)
{
--- /dev/null
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+/* DCL usage masks */
+#define WINED3DSP_DCL_USAGE_SHIFT 0
+#define WINED3DSP_DCL_USAGE_MASK (0xf << WINED3DSP_DCL_USAGE_SHIFT)
+#define WINED3DSP_DCL_USAGEINDEX_SHIFT 16
+#define WINED3DSP_DCL_USAGEINDEX_MASK (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT)
+
+/* DCL sampler type */
+#define WINED3DSP_TEXTURETYPE_SHIFT 27
+#define WINED3DSP_TEXTURETYPE_MASK (0xf << WINED3DSP_TEXTURETYPE_SHIFT)
+
+/* Opcode-related masks */
+#define WINED3DSI_OPCODE_MASK 0x0000ffff
+
+#define WINED3D_OPCODESPECIFICCONTROL_SHIFT 16
+#define WINED3D_OPCODESPECIFICCONTROL_MASK (0xff << WINED3D_OPCODESPECIFICCONTROL_SHIFT)
+
+#define WINED3DSI_INSTLENGTH_SHIFT 24
+#define WINED3DSI_INSTLENGTH_MASK (0xf << WINED3DSI_INSTLENGTH_SHIFT)
+
+#define WINED3DSI_COISSUE (1 << 30)
+
+#define WINED3DSI_COMMENTSIZE_SHIFT 16
+#define WINED3DSI_COMMENTSIZE_MASK (0x7fff << WINED3DSI_COMMENTSIZE_SHIFT)
+
+#define WINED3DSHADER_INSTRUCTION_PREDICATED (1 << 28)
+
+/* Register number mask */
+#define WINED3DSP_REGNUM_MASK 0x000007ff
+
+/* Register type masks */
+#define WINED3DSP_REGTYPE_SHIFT 28
+#define WINED3DSP_REGTYPE_MASK (0x7 << WINED3DSP_REGTYPE_SHIFT)
+#define WINED3DSP_REGTYPE_SHIFT2 8
+#define WINED3DSP_REGTYPE_MASK2 (0x18 << WINED3DSP_REGTYPE_SHIFT2)
+
+/* Relative addressing mask */
+#define WINED3DSHADER_ADDRESSMODE_SHIFT 13
+#define WINED3DSHADER_ADDRESSMODE_MASK (1 << WINED3DSHADER_ADDRESSMODE_SHIFT)
+
+/* Destination modifier mask */
+#define WINED3DSP_DSTMOD_SHIFT 20
+#define WINED3DSP_DSTMOD_MASK (0xf << WINED3DSP_DSTMOD_SHIFT)
+
+/* Destination shift mask */
+#define WINED3DSP_DSTSHIFT_SHIFT 24
+#define WINED3DSP_DSTSHIFT_MASK (0xf << WINED3DSP_DSTSHIFT_SHIFT)
+
+/* Write mask */
+#define WINED3D_SM1_WRITEMASK_SHIFT 16
+#define WINED3D_SM1_WRITEMASK_MASK (0xf << WINED3D_SM1_WRITEMASK_SHIFT)
+
+/* Swizzle mask */
+#define WINED3DSP_SWIZZLE_SHIFT 16
+#define WINED3DSP_SWIZZLE_MASK (0xff << WINED3DSP_SWIZZLE_SHIFT)
+
+/* Source modifier mask */
+#define WINED3DSP_SRCMOD_SHIFT 24
+#define WINED3DSP_SRCMOD_MASK (0xf << WINED3DSP_SRCMOD_SHIFT)
+
+#define WINED3DSP_END 0x0000ffff
+
+#define WINED3D_SM1_VERSION_MAJOR(version) (((version) >> 8) & 0xff)
+#define WINED3D_SM1_VERSION_MINOR(version) (((version) >> 0) & 0xff)
+
+enum WINED3DSHADER_ADDRESSMODE_TYPE
+{
+ WINED3DSHADER_ADDRMODE_ABSOLUTE = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT,
+ WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
+};
+
+struct wined3d_sm1_opcode_info
+{
+ unsigned int opcode;
+ UINT dst_count;
+ UINT param_count;
+ enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
+ DWORD min_version;
+ DWORD max_version;
+};
+
+struct wined3d_sm1_data
+{
+ struct wined3d_shader_version shader_version;
+ const struct wined3d_sm1_opcode_info *opcode_table;
+};
+
+/* This table is not order or position dependent. */
+static const struct wined3d_sm1_opcode_info vs_opcode_table[] =
+{
+ /* Arithmetic */
+ {WINED3DSIO_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 },
+ {WINED3DSIO_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 },
+ {WINED3DSIO_MOVA, 1, 2, WINED3DSIH_MOVA, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 },
+ {WINED3DSIO_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 },
+ {WINED3DSIO_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 },
+ {WINED3DSIO_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 },
+ {WINED3DSIO_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 },
+ {WINED3DSIO_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 },
+ {WINED3DSIO_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 },
+ {WINED3DSIO_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 },
+ {WINED3DSIO_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 },
+ {WINED3DSIO_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 },
+ {WINED3DSIO_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 },
+ {WINED3DSIO_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 },
+ {WINED3DSIO_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 },
+ {WINED3DSIO_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 },
+ {WINED3DSIO_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 },
+ {WINED3DSIO_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 },
+ {WINED3DSIO_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 },
+ {WINED3DSIO_LIT, 1, 2, WINED3DSIH_LIT, 0, 0 },
+ {WINED3DSIO_DST, 1, 3, WINED3DSIH_DST, 0, 0 },
+ {WINED3DSIO_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 },
+ {WINED3DSIO_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 },
+ {WINED3DSIO_POW, 1, 3, WINED3DSIH_POW, 0, 0 },
+ {WINED3DSIO_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 },
+ {WINED3DSIO_SGN, 1, 2, WINED3DSIH_SGN, 0, 0 },
+ {WINED3DSIO_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 },
+ {WINED3DSIO_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
+ {WINED3DSIO_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(3,0), -1 },
+ /* Matrix */
+ {WINED3DSIO_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 },
+ {WINED3DSIO_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 },
+ {WINED3DSIO_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 },
+ {WINED3DSIO_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 },
+ {WINED3DSIO_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 },
+ /* Declare registers */
+ {WINED3DSIO_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 },
+ /* Constant definitions */
+ {WINED3DSIO_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 },
+ {WINED3DSIO_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 },
+ {WINED3DSIO_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 },
+ /* Flow control */
+ {WINED3DSIO_REP, 0, 1, WINED3DSIH_REP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_IF, 0, 1, WINED3DSIH_IF, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_IFC, 0, 2, WINED3DSIH_IFC, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 },
+ {WINED3DSIO_CALL, 0, 1, WINED3DSIH_CALL, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_RET, 0, 0, WINED3DSIH_RET, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3D_SHADER_VERSION(2,0), -1 },
+
+ {WINED3DSIO_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 },
+ {WINED3DSIO_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3D_SHADER_VERSION(3,0), -1 },
+ {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 },
+};
+
+static const struct wined3d_sm1_opcode_info ps_opcode_table[] =
+{
+ /* Arithmetic */
+ {WINED3DSIO_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 },
+ {WINED3DSIO_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 },
+ {WINED3DSIO_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 },
+ {WINED3DSIO_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 },
+ {WINED3DSIO_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 },
+ {WINED3DSIO_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 },
+ {WINED3DSIO_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 },
+ {WINED3DSIO_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 },
+ {WINED3DSIO_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 },
+ {WINED3DSIO_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 },
+ {WINED3DSIO_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 },
+ {WINED3DSIO_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 },
+ {WINED3DSIO_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 },
+ {WINED3DSIO_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 },
+ {WINED3DSIO_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 },
+ {WINED3DSIO_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 },
+ {WINED3DSIO_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 },
+ {WINED3DSIO_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 },
+ {WINED3DSIO_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 },
+ {WINED3DSIO_DST, 1, 3, WINED3DSIH_DST, 0, 0 },
+ {WINED3DSIO_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 },
+ {WINED3DSIO_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 },
+ {WINED3DSIO_CND, 1, 4, WINED3DSIH_CND, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3DSIO_CMP, 1, 4, WINED3DSIH_CMP, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(3,0)},
+ {WINED3DSIO_POW, 1, 3, WINED3DSIH_POW, 0, 0 },
+ {WINED3DSIO_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 },
+ {WINED3DSIO_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 },
+ {WINED3DSIO_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
+ {WINED3DSIO_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3DSIO_DP2ADD, 1, 4, WINED3DSIH_DP2ADD, WINED3D_SHADER_VERSION(2,0), -1 },
+ /* Matrix */
+ {WINED3DSIO_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 },
+ {WINED3DSIO_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 },
+ {WINED3DSIO_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 },
+ {WINED3DSIO_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 },
+ {WINED3DSIO_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 },
+ /* Register declarations */
+ {WINED3DSIO_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 },
+ /* Flow control */
+ {WINED3DSIO_REP, 0, 1, WINED3DSIH_REP, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_IF, 0, 1, WINED3DSIH_IF, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_IFC, 0, 2, WINED3DSIH_IFC, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 },
+ {WINED3DSIO_CALL, 0, 1, WINED3DSIH_CALL, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3DSIO_RET, 0, 0, WINED3DSIH_RET, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3DSIO_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3D_SHADER_VERSION(2,1), -1 },
+ /* Constant definitions */
+ {WINED3DSIO_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 },
+ {WINED3DSIO_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 },
+ {WINED3DSIO_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 },
+ /* Texture */
+ {WINED3DSIO_TEXCOORD, 1, 1, WINED3DSIH_TEXCOORD, 0, WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXCOORD, 1, 2, WINED3DSIH_TEXCOORD, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3DSIO_TEXKILL, 1, 1, WINED3DSIH_TEXKILL, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(3,0)},
+ {WINED3DSIO_TEX, 1, 1, WINED3DSIH_TEX, 0, WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEX, 1, 2, WINED3DSIH_TEX, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3DSIO_TEX, 1, 3, WINED3DSIH_TEX, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3DSIO_TEXBEM, 1, 2, WINED3DSIH_TEXBEM, 0, WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXBEML, 1, 2, WINED3DSIH_TEXBEML, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXREG2AR, 1, 2, WINED3DSIH_TEXREG2AR, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXREG2GB, 1, 2, WINED3DSIH_TEXREG2GB, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXREG2RGB, 1, 2, WINED3DSIH_TEXREG2RGB, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x2PAD, 1, 2, WINED3DSIH_TEXM3x2PAD, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x2TEX, 1, 2, WINED3DSIH_TEXM3x2TEX, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x3PAD, 1, 2, WINED3DSIH_TEXM3x3PAD, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x3DIFF, 1, 2, WINED3DSIH_TEXM3x3DIFF, WINED3D_SHADER_VERSION(0,0), WINED3D_SHADER_VERSION(0,0)},
+ {WINED3DSIO_TEXM3x3SPEC, 1, 3, WINED3DSIH_TEXM3x3SPEC, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x3VSPEC, 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x3TEX, 1, 2, WINED3DSIH_TEXM3x3TEX, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXDP3TEX, 1, 2, WINED3DSIH_TEXDP3TEX, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x2DEPTH, 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3D_SHADER_VERSION(1,3), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXDP3, 1, 2, WINED3DSIH_TEXDP3, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXM3x3, 1, 2, WINED3DSIH_TEXM3x3, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3DSIO_TEXDEPTH, 1, 1, WINED3DSIH_TEXDEPTH, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3DSIO_BEM, 1, 3, WINED3DSIH_BEM, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3DSIO_DSX, 1, 2, WINED3DSIH_DSX, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_DSY, 1, 2, WINED3DSIH_DSY, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_TEXLDD, 1, 5, WINED3DSIH_TEXLDD, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3DSIO_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 },
+ {WINED3DSIO_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3DSIO_PHASE, 0, 0, WINED3DSIH_PHASE, 0, 0 },
+ {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 },
+};
+
+/* Read a parameter opcode from the input stream,
+ * and possibly a relative addressing token.
+ * Return the number of tokens read */
+static int shader_get_param(const struct wined3d_sm1_data *priv, const DWORD *ptr, DWORD *token, DWORD *addr_token)
+{
+ UINT count = 1;
+
+ *token = *ptr;
+
+ /* PS >= 3.0 have relative addressing (with token)
+ * VS >= 2.0 have relative addressing (with token)
+ * VS >= 1.0 < 2.0 have relative addressing (without token)
+ * The version check below should work in general */
+ if (*ptr & WINED3DSHADER_ADDRMODE_RELATIVE)
+ {
+ if (priv->shader_version.major < 2)
+ {
+ *addr_token = (1 << 31)
+ | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT2) & WINED3DSP_REGTYPE_MASK2)
+ | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT) & WINED3DSP_REGTYPE_MASK)
+ | (WINED3DSP_NOSWIZZLE << WINED3DSP_SWIZZLE_SHIFT);
+ }
+ else
+ {
+ *addr_token = *(ptr + 1);
+ ++count;
+ }
+ }
+
+ return count;
+}
+
+static const struct wined3d_sm1_opcode_info *shader_get_opcode(const struct wined3d_sm1_data *priv, DWORD code)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(priv->shader_version.major, priv->shader_version.minor);
+ const struct wined3d_sm1_opcode_info *opcode_table = priv->opcode_table;
+ DWORD i = 0;
+
+ while (opcode_table[i].handler_idx != WINED3DSIH_TABLE_SIZE)
+ {
+ if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode
+ && shader_version >= opcode_table[i].min_version
+ && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version))
+ {
+ return &opcode_table[i];
+ }
+ ++i;
+ }
+
+ FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n",
+ code, code, code & WINED3DSI_OPCODE_MASK, shader_version);
+
+ return NULL;
+}
+
+/* Return the number of parameters to skip for an opcode */
+static int shader_skip_opcode(const struct wined3d_sm1_data *priv,
+ const struct wined3d_sm1_opcode_info *opcode_info, DWORD opcode_token)
+{
+ /* Shaders >= 2.0 may contain address tokens, but fortunately they
+ * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */
+ return (priv->shader_version.major >= 2)
+ ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : opcode_info->param_count;
+}
+
+static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr,
+ struct wined3d_shader_src_param *src)
+{
+ src->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
+ | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
+ src->reg.idx = param & WINED3DSP_REGNUM_MASK;
+ src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+ src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT;
+ src->reg.rel_addr = rel_addr;
+}
+
+static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr,
+ struct wined3d_shader_dst_param *dst)
+{
+ dst->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
+ | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
+ dst->reg.idx = param & WINED3DSP_REGNUM_MASK;
+ dst->write_mask = (param & WINED3D_SM1_WRITEMASK_MASK) >> WINED3D_SM1_WRITEMASK_SHIFT;
+ dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT;
+ dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
+ dst->reg.rel_addr = rel_addr;
+}
+
+/* Read the parameters of an unrecognized opcode from the input stream
+ * Return the number of tokens read.
+ *
+ * Note: This function assumes source or destination token format.
+ * It will not work with specially-formatted tokens like DEF or DCL,
+ * but hopefully those would be recognized */
+static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const DWORD *ptr)
+{
+ int tokens_read = 0;
+ int i = 0;
+
+ /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
+ while (*ptr & 0x80000000)
+ {
+ DWORD token, addr_token = 0;
+ struct wined3d_shader_src_param rel_addr;
+
+ tokens_read += shader_get_param(priv, ptr, &token, &addr_token);
+ ptr += tokens_read;
+
+ FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x name=", token, addr_token);
+
+ if (token & WINED3DSHADER_ADDRMODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr);
+
+ if (!i)
+ {
+ struct wined3d_shader_dst_param dst;
+
+ shader_parse_dst_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &dst);
+ shader_dump_dst_param(&dst, &priv->shader_version);
+ }
+ else
+ {
+ struct wined3d_shader_src_param src;
+
+ shader_parse_src_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &src);
+ shader_dump_src_param(&src, &priv->shader_version);
+ }
+ FIXME("\n");
+ ++i;
+ }
+ return tokens_read;
+}
+
+static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
+{
+ struct wined3d_sm1_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
+ if (!priv)
+ {
+ ERR("Failed to allocate private data\n");
+ return NULL;
+ }
+
+ if (output_signature)
+ {
+ FIXME("SM 1-3 shader shouldn't have output signatures.\n");
+ }
+
+ switch (*byte_code >> 16)
+ {
+ case WINED3D_SM1_VS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
+ priv->opcode_table = vs_opcode_table;
+ break;
+
+ case WINED3D_SM1_PS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
+ priv->opcode_table = ps_opcode_table;
+ break;
+
+ default:
+ FIXME("Unrecognized shader type %#x\n", *byte_code >> 16);
+ HeapFree(GetProcessHeap(), 0, priv);
+ return NULL;
+ }
+
+ return priv;
+}
+
+static void shader_sm1_free(void *data)
+{
+ HeapFree(GetProcessHeap(), 0, data);
+}
+
+static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
+{
+ struct wined3d_sm1_data *priv = data;
+ DWORD version_token;
+
+ version_token = *(*ptr)++;
+ TRACE("version: 0x%08x\n", version_token);
+
+ priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(version_token);
+ priv->shader_version.minor = WINED3D_SM1_VERSION_MINOR(version_token);
+ *shader_version = priv->shader_version;
+}
+
+static void shader_sm1_read_opcode(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins,
+ UINT *param_size)
+{
+ struct wined3d_sm1_data *priv = data;
+ const struct wined3d_sm1_opcode_info *opcode_info;
+ DWORD opcode_token;
+
+ opcode_token = *(*ptr)++;
+ opcode_info = shader_get_opcode(priv, opcode_token);
+ if (!opcode_info)
+ {
+ FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
+ ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+ *param_size = shader_skip_unrecognized(priv, *ptr);
+ return;
+ }
+
+ ins->handler_idx = opcode_info->handler_idx;
+ ins->flags = (opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK) >> WINED3D_OPCODESPECIFICCONTROL_SHIFT;
+ ins->coissue = opcode_token & WINED3DSI_COISSUE;
+ ins->predicate = opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED;
+ ins->dst_count = opcode_info->dst_count ? 1 : 0;
+ ins->src_count = opcode_info->param_count - opcode_info->dst_count;
+ *param_size = shader_skip_opcode(priv, opcode_info, opcode_token);
+}
+
+static void shader_sm1_read_src_param(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param,
+ struct wined3d_shader_src_param *src_rel_addr)
+{
+ struct wined3d_sm1_data *priv = data;
+ DWORD token, addr_token;
+
+ *ptr += shader_get_param(priv, *ptr, &token, &addr_token);
+ if (token & WINED3DSHADER_ADDRMODE_RELATIVE)
+ {
+ shader_parse_src_param(addr_token, NULL, src_rel_addr);
+ shader_parse_src_param(token, src_rel_addr, src_param);
+ }
+ else
+ {
+ shader_parse_src_param(token, NULL, src_param);
+ }
+}
+
+static void shader_sm1_read_dst_param(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
+ struct wined3d_shader_src_param *dst_rel_addr)
+{
+ struct wined3d_sm1_data *priv = data;
+ DWORD token, addr_token;
+
+ *ptr += shader_get_param(priv, *ptr, &token, &addr_token);
+ if (token & WINED3DSHADER_ADDRMODE_RELATIVE)
+ {
+ shader_parse_src_param(addr_token, NULL, dst_rel_addr);
+ shader_parse_dst_param(token, dst_rel_addr, dst_param);
+ }
+ else
+ {
+ shader_parse_dst_param(token, NULL, dst_param);
+ }
+}
+
+static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
+{
+ DWORD usage_token = *(*ptr)++;
+ DWORD dst_token = *(*ptr)++;
+
+ semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
+ semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
+ semantic->sampler_type = (usage_token & WINED3DSP_TEXTURETYPE_MASK) >> WINED3DSP_TEXTURETYPE_SHIFT;
+ shader_parse_dst_param(dst_token, NULL, &semantic->reg);
+}
+
+static void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
+{
+ DWORD token = **ptr;
+
+ if ((token & WINED3DSI_OPCODE_MASK) != WINED3DSIO_COMMENT)
+ {
+ *comment = NULL;
+ return;
+ }
+
+ *comment = (const char *)++(*ptr);
+ *ptr += (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
+}
+
+static BOOL shader_sm1_is_end(void *data, const DWORD **ptr)
+{
+ if (**ptr == WINED3DSP_END)
+ {
+ ++(*ptr);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+const struct wined3d_shader_frontend sm1_shader_frontend =
+{
+ shader_sm1_init,
+ shader_sm1_free,
+ shader_sm1_read_header,
+ shader_sm1_read_opcode,
+ shader_sm1_read_src_param,
+ shader_sm1_read_dst_param,
+ shader_sm1_read_semantic,
+ shader_sm1_read_comment,
+ shader_sm1_is_end,
+};
--- /dev/null
+/*
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+#define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT 24
+#define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0xf << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
+
+#define WINED3D_SM4_OPCODE_MASK 0xff
+
+#define WINED3D_SM4_REGISTER_TYPE_SHIFT 12
+#define WINED3D_SM4_REGISTER_TYPE_MASK (0xf << WINED3D_SM4_REGISTER_TYPE_SHIFT)
+
+#define WINED3D_SM4_IMMCONST_TYPE_SHIFT 0
+#define WINED3D_SM4_IMMCONST_TYPE_MASK (0x3 << WINED3D_SM4_IMMCONST_TYPE_SHIFT)
+
+#define WINED3D_SM4_WRITEMASK_SHIFT 4
+#define WINED3D_SM4_WRITEMASK_MASK (0xf << WINED3D_SM4_WRITEMASK_SHIFT)
+
+#define WINED3D_SM4_SWIZZLE_SHIFT 4
+#define WINED3D_SM4_SWIZZLE_MASK (0xff << WINED3D_SM4_SWIZZLE_SHIFT)
+
+#define WINED3D_SM4_VERSION_MAJOR(version) (((version) >> 4) & 0xf)
+#define WINED3D_SM4_VERSION_MINOR(version) (((version) >> 0) & 0xf)
+
+enum wined3d_sm4_opcode
+{
+ WINED3D_SM4_OP_ADD = 0x00,
+ WINED3D_SM4_OP_EXP = 0x19,
+ WINED3D_SM4_OP_MOV = 0x36,
+ WINED3D_SM4_OP_MUL = 0x38,
+ WINED3D_SM4_OP_RET = 0x3e,
+ WINED3D_SM4_OP_SINCOS = 0x4d,
+};
+
+enum wined3d_sm4_register_type
+{
+ WINED3D_SM4_RT_TEMP = 0x0,
+ WINED3D_SM4_RT_INPUT = 0x1,
+ WINED3D_SM4_RT_OUTPUT = 0x2,
+ WINED3D_SM4_RT_IMMCONST = 0x4,
+};
+
+enum wined3d_sm4_immconst_type
+{
+ WINED3D_SM4_IMMCONST_FLOAT = 0x1,
+ WINED3D_SM4_IMMCONST_FLOAT4 = 0x2,
+};
+
+struct wined3d_sm4_data
+{
+ struct wined3d_shader_version shader_version;
+ const DWORD *end;
+ const struct wined3d_shader_signature *output_signature;
+};
+
+struct wined3d_sm4_opcode_info
+{
+ enum wined3d_sm4_opcode opcode;
+ enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
+ UINT dst_count;
+ UINT src_count;
+};
+
+struct sysval_map
+{
+ enum wined3d_sysval_semantic sysval;
+ WINED3DSHADER_PARAM_REGISTER_TYPE register_type;
+ UINT register_idx;
+};
+
+static const struct wined3d_sm4_opcode_info opcode_table[] =
+{
+ {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, 1, 2},
+ {WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, 1, 1},
+ {WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, 1, 1},
+ {WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, 1, 2},
+ {WINED3D_SM4_OP_RET, WINED3DSIH_RET, 0, 0},
+ {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, 1, 2},
+};
+
+static const WINED3DSHADER_PARAM_REGISTER_TYPE register_type_table[] =
+{
+ /* WINED3D_SM4_RT_TEMP */ WINED3DSPR_TEMP,
+ /* WINED3D_SM4_RT_INPUT */ WINED3DSPR_INPUT,
+ /* WINED3D_SM4_RT_OUTPUT */ WINED3DSPR_OUTPUT,
+ /* UNKNOWN */ 0,
+ /* WINED3D_SM4_RT_IMMCONST */ WINED3DSPR_IMMCONST,
+};
+
+static const struct sysval_map sysval_map[] =
+{
+ {WINED3D_SV_DEPTH, WINED3DSPR_DEPTHOUT, 0},
+ {WINED3D_SV_TARGET0, WINED3DSPR_COLOROUT, 0},
+ {WINED3D_SV_TARGET1, WINED3DSPR_COLOROUT, 1},
+ {WINED3D_SV_TARGET2, WINED3DSPR_COLOROUT, 2},
+ {WINED3D_SV_TARGET3, WINED3DSPR_COLOROUT, 3},
+ {WINED3D_SV_TARGET4, WINED3DSPR_COLOROUT, 4},
+ {WINED3D_SV_TARGET5, WINED3DSPR_COLOROUT, 5},
+ {WINED3D_SV_TARGET6, WINED3DSPR_COLOROUT, 6},
+ {WINED3D_SV_TARGET7, WINED3DSPR_COLOROUT, 7},
+};
+
+static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_opcode opcode)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(opcode_table) / sizeof(*opcode_table); ++i)
+ {
+ if (opcode == opcode_table[i].opcode) return &opcode_table[i];
+ }
+
+ return NULL;
+}
+
+static void map_sysval(enum wined3d_sysval_semantic sysval, struct wined3d_shader_register *reg)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(sysval_map) / sizeof(*sysval_map); ++i)
+ {
+ if (sysval == sysval_map[i].sysval)
+ {
+ reg->type = sysval_map[i].register_type;
+ reg->idx = sysval_map[i].register_idx;
+ }
+ }
+}
+
+static void map_register(struct wined3d_sm4_data *priv, struct wined3d_shader_register *reg)
+{
+ switch (priv->shader_version.type)
+ {
+ case WINED3D_SHADER_TYPE_PIXEL:
+ if (reg->type == WINED3DSPR_OUTPUT)
+ {
+ unsigned int i;
+ const struct wined3d_shader_signature *s = priv->output_signature;
+
+ if (!s)
+ {
+ ERR("Shader has no output signature, unable to map register.\n");
+ break;
+ }
+
+ for (i = 0; i < s->element_count; ++i)
+ {
+ if (s->elements[i].register_idx == reg->idx)
+ {
+ map_sysval(s->elements[i].sysval_semantic, reg);
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
+{
+ struct wined3d_sm4_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
+ if (!priv)
+ {
+ ERR("Failed to allocate private data\n");
+ return NULL;
+ }
+
+ priv->output_signature = output_signature;
+
+ return priv;
+}
+
+static void shader_sm4_free(void *data)
+{
+ HeapFree(GetProcessHeap(), 0, data);
+}
+
+static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
+{
+ struct wined3d_sm4_data *priv = data;
+ DWORD version_token;
+
+ priv->end = *ptr;
+
+ version_token = *(*ptr)++;
+ TRACE("version: 0x%08x\n", version_token);
+
+ TRACE("token count: %u\n", **ptr);
+ priv->end += *(*ptr)++;
+
+ switch (version_token >> 16)
+ {
+ case WINED3D_SM4_PS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
+ break;
+
+ case WINED3D_SM4_VS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
+ break;
+
+ case WINED3D_SM4_GS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
+ break;
+
+ default:
+ FIXME("Unrecognized shader type %#x\n", version_token >> 16);
+ }
+ priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token);
+ priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token);
+
+ *shader_version = priv->shader_version;
+}
+
+static void shader_sm4_read_opcode(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins,
+ UINT *param_size)
+{
+ const struct wined3d_sm4_opcode_info *opcode_info;
+ DWORD token = *(*ptr)++;
+ DWORD opcode = token & WINED3D_SM4_OPCODE_MASK;
+
+ *param_size = ((token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) - 1;
+
+ opcode_info = get_opcode_info(opcode);
+ if (!opcode_info)
+ {
+ FIXME("Unrecognized opcode %#x, token 0x%08x\n", opcode, token);
+ ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+ return;
+ }
+
+ ins->handler_idx = opcode_info->handler_idx;
+ ins->flags = 0;
+ ins->coissue = 0;
+ ins->predicate = 0;
+ ins->dst_count = opcode_info->dst_count;
+ ins->src_count = opcode_info->src_count;
+}
+
+static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param,
+ struct wined3d_shader_src_param *src_rel_addr)
+{
+ struct wined3d_sm4_data *priv = data;
+ DWORD token = *(*ptr)++;
+ enum wined3d_sm4_register_type register_type;
+
+ register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
+ if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
+ {
+ FIXME("Unhandled register type %#x\n", register_type);
+ src_param->reg.type = WINED3DSPR_TEMP;
+ }
+ else
+ {
+ src_param->reg.type = register_type_table[register_type];
+ }
+
+ if (register_type == WINED3D_SM4_RT_IMMCONST)
+ {
+ enum wined3d_sm4_immconst_type immconst_type =
+ (token & WINED3D_SM4_IMMCONST_TYPE_MASK) >> WINED3D_SM4_IMMCONST_TYPE_SHIFT;
+ src_param->swizzle = WINED3DSP_NOSWIZZLE;
+
+ switch(immconst_type)
+ {
+ case WINED3D_SM4_IMMCONST_FLOAT:
+ src_param->reg.immconst_type = WINED3D_IMMCONST_FLOAT;
+ memcpy(src_param->reg.immconst_data, *ptr, 1 * sizeof(DWORD));
+ *ptr += 1;
+ break;
+
+ case WINED3D_SM4_IMMCONST_FLOAT4:
+ src_param->reg.immconst_type = WINED3D_IMMCONST_FLOAT4;
+ memcpy(src_param->reg.immconst_data, *ptr, 4 * sizeof(DWORD));
+ *ptr += 4;
+ break;
+
+ default:
+ FIXME("Unhandled immediate constant type %#x\n", immconst_type);
+ break;
+ }
+ }
+ else
+ {
+ src_param->reg.idx = *(*ptr)++;
+ src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT;
+ }
+
+ src_param->modifiers = 0;
+ src_param->reg.rel_addr = NULL;
+
+ map_register(priv, &src_param->reg);
+}
+
+static void shader_sm4_read_dst_param(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
+ struct wined3d_shader_src_param *dst_rel_addr)
+{
+ struct wined3d_sm4_data *priv = data;
+ DWORD token = *(*ptr)++;
+ UINT register_idx = *(*ptr)++;
+ enum wined3d_sm4_register_type register_type;
+
+ register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
+ if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
+ {
+ FIXME("Unhandled register type %#x\n", register_type);
+ dst_param->reg.type = WINED3DSPR_TEMP;
+ }
+ else
+ {
+ dst_param->reg.type = register_type_table[register_type];
+ }
+
+ dst_param->reg.idx = register_idx;
+ dst_param->write_mask = (token & WINED3D_SM4_WRITEMASK_MASK) >> WINED3D_SM4_WRITEMASK_SHIFT;
+ dst_param->modifiers = 0;
+ dst_param->shift = 0;
+ dst_param->reg.rel_addr = NULL;
+
+ map_register(priv, &dst_param->reg);
+}
+
+static void shader_sm4_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
+{
+ FIXME("ptr %p, semantic %p stub!\n", ptr, semantic);
+}
+
+static void shader_sm4_read_comment(const DWORD **ptr, const char **comment)
+{
+ FIXME("ptr %p, comment %p stub!\n", ptr, comment);
+ *comment = NULL;
+}
+
+static BOOL shader_sm4_is_end(void *data, const DWORD **ptr)
+{
+ struct wined3d_sm4_data *priv = data;
+ return *ptr == priv->end;
+}
+
+const struct wined3d_shader_frontend sm4_shader_frontend =
+{
+ shader_sm4_init,
+ shader_sm4_free,
+ shader_sm4_read_header,
+ shader_sm4_read_opcode,
+ shader_sm4_read_src_param,
+ shader_sm4_read_dst_param,
+ shader_sm4_read_semantic,
+ shader_sm4_read_comment,
+ shader_sm4_is_end,
+};
}
static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+ BOOL warned = FALSE;
/* TODO: NV_POINT_SPRITE */
- if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
- TRACE("Point sprites not supported\n");
+ if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
+ /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
+ FIXME("Point sprites not supported\n");
+ warned = TRUE;
}
}
static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
+ BOOL warned = FALSE;
+ if(GL_LIMITS(point_sprite_units) < GL_LIMITS(textures) && !warned) {
+ if(use_ps(stateblock) || stateblock->lowest_disabled_stage > GL_LIMITS(point_sprite_units)) {
+ FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n");
+ warned = TRUE;
+ }
+ }
+
glEnable(GL_POINT_SPRITE_ARB);
checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
} else {
if (stream_info->elements[i].buffer_object)
{
vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
- ptr += (long) vb->resource.allocatedMemory;
+ ptr += (long) buffer_get_sysmem(vb);
}
if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
*target_bpp = 6;
break;
+ case WINED3DFMT_R16G16_FLOAT:
+ *convert = CONVERT_R16G16F;
+ *format = GL_RGB;
+ *internal = GL_RGB16F_ARB;
+ *type = GL_HALF_FLOAT_ARB;
+ *target_bpp = 6;
+ break;
+
+ case WINED3DFMT_R32G32_FLOAT:
+ *convert = CONVERT_R32G32F;
+ *format = GL_RGB;
+ *internal = GL_RGB32F_ARB;
+ *type = GL_FLOAT;
+ *target_bpp = 12;
+ break;
+
default:
break;
}
}
case CONVERT_G16R16:
+ case CONVERT_R16G16F:
{
unsigned int x, y;
const WORD *Source;
WORD red = (*Source++);
Dest[0] = green;
Dest[1] = red;
+ /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
+ * shader overwrites it anyway
+ */
Dest[2] = 0xffff;
Dest += 3;
}
break;
}
+ case CONVERT_R32G32F:
+ {
+ unsigned int x, y;
+ const float *Source;
+ float *Dest;
+ for(y = 0; y < height; y++) {
+ Source = (const float *)(src + y * pitch);
+ Dest = (float *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ ) {
+ float green = (*Source++);
+ float red = (*Source++);
+ Dest[0] = green;
+ Dest[1] = red;
+ Dest[2] = 1.0;
+ Dest += 3;
+ }
+ }
+ break;
+ }
+
default:
ERR("Unsupported conversation type %d\n", convert);
}
return NULL;
}
- IWineD3DDevice_CreateSurface((IWineD3DDevice *) source->resource.wineD3DDevice,
- source->currentDesc.Width,
- source->currentDesc.Height,
- to_fmt,
- TRUE, /* lockable */
- TRUE, /* discard */
- 0, /* level */
- &ret,
- WINED3DRTYPE_SURFACE,
- 0, /* usage */
- WINED3DPOOL_SCRATCH,
- WINED3DMULTISAMPLE_NONE, /* TODO: Multisampled conversion */
- 0, /* MultiSampleQuality */
- NULL, /* SharedHandle */
- IWineD3DSurface_GetImplType((IWineD3DSurface *) source),
- NULL); /* parent */
+ IWineD3DDevice_CreateSurface((IWineD3DDevice *)source->resource.wineD3DDevice,
+ source->currentDesc.Width, source->currentDesc.Height, to_fmt, TRUE /* lockable */,
+ TRUE /* discard */, 0 /* level */, &ret, WINED3DRTYPE_SURFACE, 0 /* usage */,
+ WINED3DPOOL_SCRATCH, WINED3DMULTISAMPLE_NONE /* TODO: Multisampled conversion */,
+ 0 /* MultiSampleQuality */, IWineD3DSurface_GetImplType((IWineD3DSurface *) source), NULL /* parent */);
if(!ret) {
ERR("Failed to create a destination surface for conversion\n");
return NULL;
/* Already locked? */
if(This->Flags & SFLAG_LOCKED)
{
- ERR("(%p) Surface already locked\n", This);
+ WARN("(%p) Surface already locked\n", This);
/* What should I return here? */
return WINED3DERR_INVALIDCALL;
}
gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
}
- if (GL_SUPPORT(NV_HALF_FLOAT))
+ if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
{
/* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
* It is the job of the vertex buffer code to make sure that the vbos have the right format */
idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
- gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT_NV;
+ gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
- gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT_NV;
+ gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
}
}
if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
{
- if (!GL_SUPPORT(NV_HALF_FLOAT)) This->half_float_conv_needed = TRUE;
+ if (!GL_SUPPORT(ARB_HALF_FLOAT_VERTEX)) This->half_float_conv_needed = TRUE;
}
}
#define GLINFO_LOCATION ((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info
-/* 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 */
-
-CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
- /* This table is not order or position dependent. */
-
- /* Arithmetic */
- {WINED3DSIO_NOP, "nop", 0, 0, WINED3DSIH_NOP, 0, 0 },
- {WINED3DSIO_MOV, "mov", 1, 2, WINED3DSIH_MOV, 0, 0 },
- {WINED3DSIO_MOVA, "mova", 1, 2, WINED3DSIH_MOVA, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_ADD, "add", 1, 3, WINED3DSIH_ADD, 0, 0 },
- {WINED3DSIO_SUB, "sub", 1, 3, WINED3DSIH_SUB, 0, 0 },
- {WINED3DSIO_MAD, "mad", 1, 4, WINED3DSIH_MAD, 0, 0 },
- {WINED3DSIO_MUL, "mul", 1, 3, WINED3DSIH_MUL, 0, 0 },
- {WINED3DSIO_RCP, "rcp", 1, 2, WINED3DSIH_RCP, 0, 0 },
- {WINED3DSIO_RSQ, "rsq", 1, 2, WINED3DSIH_RSQ, 0, 0 },
- {WINED3DSIO_DP3, "dp3", 1, 3, WINED3DSIH_DP3, 0, 0 },
- {WINED3DSIO_DP4, "dp4", 1, 3, WINED3DSIH_DP4, 0, 0 },
- {WINED3DSIO_MIN, "min", 1, 3, WINED3DSIH_MIN, 0, 0 },
- {WINED3DSIO_MAX, "max", 1, 3, WINED3DSIH_MAX, 0, 0 },
- {WINED3DSIO_SLT, "slt", 1, 3, WINED3DSIH_SLT, 0, 0 },
- {WINED3DSIO_SGE, "sge", 1, 3, WINED3DSIH_SGE, 0, 0 },
- {WINED3DSIO_ABS, "abs", 1, 2, WINED3DSIH_ABS, 0, 0 },
- {WINED3DSIO_EXP, "exp", 1, 2, WINED3DSIH_EXP, 0, 0 },
- {WINED3DSIO_LOG, "log", 1, 2, WINED3DSIH_LOG, 0, 0 },
- {WINED3DSIO_EXPP, "expp", 1, 2, WINED3DSIH_EXPP, 0, 0 },
- {WINED3DSIO_LOGP, "logp", 1, 2, WINED3DSIH_LOGP, 0, 0 },
- {WINED3DSIO_LIT, "lit", 1, 2, WINED3DSIH_LIT, 0, 0 },
- {WINED3DSIO_DST, "dst", 1, 3, WINED3DSIH_DST, 0, 0 },
- {WINED3DSIO_LRP, "lrp", 1, 4, WINED3DSIH_LRP, 0, 0 },
- {WINED3DSIO_FRC, "frc", 1, 2, WINED3DSIH_FRC, 0, 0 },
- {WINED3DSIO_POW, "pow", 1, 3, WINED3DSIH_POW, 0, 0 },
- {WINED3DSIO_CRS, "crs", 1, 3, WINED3DSIH_CRS, 0, 0 },
- /* TODO: sng can possibly be performed as
- RCP tmp, vec
- MUL out, tmp, vec*/
- {WINED3DSIO_SGN, "sgn", 1, 2, WINED3DSIH_SGN, 0, 0 },
- {WINED3DSIO_NRM, "nrm", 1, 2, WINED3DSIH_NRM, 0, 0 },
- {WINED3DSIO_SINCOS, "sincos", 1, 4, WINED3DSIH_SINCOS, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
- {WINED3DSIO_SINCOS, "sincos", 1, 2, WINED3DSIH_SINCOS, WINED3DVS_VERSION(3,0), -1 },
- /* Matrix */
- {WINED3DSIO_M4x4, "m4x4", 1, 3, WINED3DSIH_M4x4, 0, 0 },
- {WINED3DSIO_M4x3, "m4x3", 1, 3, WINED3DSIH_M4x3, 0, 0 },
- {WINED3DSIO_M3x4, "m3x4", 1, 3, WINED3DSIH_M3x4, 0, 0 },
- {WINED3DSIO_M3x3, "m3x3", 1, 3, WINED3DSIH_M3x3, 0, 0 },
- {WINED3DSIO_M3x2, "m3x2", 1, 3, WINED3DSIH_M3x2, 0, 0 },
- /* Declare registers */
- {WINED3DSIO_DCL, "dcl", 0, 2, WINED3DSIH_DCL, 0, 0 },
- /* Constant definitions */
- {WINED3DSIO_DEF, "def", 1, 5, WINED3DSIH_DEF, 0, 0 },
- {WINED3DSIO_DEFB, "defb", 1, 2, WINED3DSIH_DEFB, 0, 0 },
- {WINED3DSIO_DEFI, "defi", 1, 5, WINED3DSIH_DEFI, 0, 0 },
- /* Flow control - requires GLSL or software shaders */
- {WINED3DSIO_REP , "rep", 0, 1, WINED3DSIH_REP, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_ENDREP, "endrep", 0, 0, WINED3DSIH_ENDREP, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_IF, "if", 0, 1, WINED3DSIH_IF, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_IFC, "ifc", 0, 2, WINED3DSIH_IFC, WINED3DVS_VERSION(2,1), -1 },
- {WINED3DSIO_ELSE, "else", 0, 0, WINED3DSIH_ELSE, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_ENDIF, "endif", 0, 0, WINED3DSIH_ENDIF, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_BREAK, "break", 0, 0, WINED3DSIH_BREAK, WINED3DVS_VERSION(2,1), -1 },
- {WINED3DSIO_BREAKC, "breakc", 0, 2, WINED3DSIH_BREAKC, WINED3DVS_VERSION(2,1), -1 },
- {WINED3DSIO_BREAKP, "breakp", 0, 1, WINED3DSIH_BREAKP, 0, 0 },
- {WINED3DSIO_CALL, "call", 0, 1, WINED3DSIH_CALL, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_CALLNZ, "callnz", 0, 2, WINED3DSIH_CALLNZ, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_LOOP, "loop", 0, 2, WINED3DSIH_LOOP, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_RET, "ret", 0, 0, WINED3DSIH_RET, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_ENDLOOP, "endloop", 0, 0, WINED3DSIH_ENDLOOP, WINED3DVS_VERSION(2,0), -1 },
- {WINED3DSIO_LABEL, "label", 0, 1, WINED3DSIH_LABEL, WINED3DVS_VERSION(2,0), -1 },
-
- {WINED3DSIO_SETP, "setp", 1, 3, WINED3DSIH_SETP, 0, 0 },
- {WINED3DSIO_TEXLDL, "texldl", 1, 3, WINED3DSIH_TEXLDL, WINED3DVS_VERSION(3,0), -1 },
- {0, NULL, 0, 0, 0, 0, 0 }
-};
+static void vshader_set_limits(IWineD3DVertexShaderImpl *This)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(This->baseShader.reg_maps.shader_version.major,
+ This->baseShader.reg_maps.shader_version.minor);
-static void vshader_set_limits(
- IWineD3DVertexShaderImpl *This) {
-
- This->baseShader.limits.texcoord = 0;
- This->baseShader.limits.attributes = 16;
- This->baseShader.limits.packed_input = 0;
-
- /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
- This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
-
- switch (This->baseShader.reg_maps.shader_version)
- {
- case WINED3DVS_VERSION(1,0):
- case WINED3DVS_VERSION(1,1):
- This->baseShader.limits.temporary = 12;
- This->baseShader.limits.constant_bool = 0;
- This->baseShader.limits.constant_int = 0;
- This->baseShader.limits.address = 1;
- This->baseShader.limits.packed_output = 0;
- This->baseShader.limits.sampler = 0;
- This->baseShader.limits.label = 0;
- break;
-
- case WINED3DVS_VERSION(2,0):
- case WINED3DVS_VERSION(2,1):
- This->baseShader.limits.temporary = 12;
- This->baseShader.limits.constant_bool = 16;
- This->baseShader.limits.constant_int = 16;
- This->baseShader.limits.address = 1;
- This->baseShader.limits.packed_output = 0;
- This->baseShader.limits.sampler = 0;
- This->baseShader.limits.label = 16;
- break;
-
- case WINED3DVS_VERSION(3,0):
- This->baseShader.limits.temporary = 32;
- This->baseShader.limits.constant_bool = 32;
- This->baseShader.limits.constant_int = 32;
- This->baseShader.limits.address = 1;
- This->baseShader.limits.packed_output = 12;
- This->baseShader.limits.sampler = 4;
- This->baseShader.limits.label = 16; /* FIXME: 2048 */
- break;
-
- default: This->baseShader.limits.temporary = 12;
- This->baseShader.limits.constant_bool = 16;
- This->baseShader.limits.constant_int = 16;
- This->baseShader.limits.address = 1;
- This->baseShader.limits.packed_output = 0;
- This->baseShader.limits.sampler = 0;
- This->baseShader.limits.label = 16;
- FIXME("Unrecognized vertex shader version %#x\n",
- This->baseShader.reg_maps.shader_version);
- }
+ This->baseShader.limits.texcoord = 0;
+ This->baseShader.limits.attributes = 16;
+ This->baseShader.limits.packed_input = 0;
+
+ switch (shader_version)
+ {
+ case WINED3D_SHADER_VERSION(1,0):
+ case WINED3D_SHADER_VERSION(1,1):
+ This->baseShader.limits.temporary = 12;
+ This->baseShader.limits.constant_bool = 0;
+ This->baseShader.limits.constant_int = 0;
+ This->baseShader.limits.address = 1;
+ This->baseShader.limits.packed_output = 0;
+ This->baseShader.limits.sampler = 0;
+ This->baseShader.limits.label = 0;
+ /* TODO: vs_1_1 has a minimum of 96 constants. What happens if a vs_1_1 shader is used
+ * on a vs_3_0 capable card that has 256 constants? */
+ This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+ break;
+
+ case WINED3D_SHADER_VERSION(2,0):
+ case WINED3D_SHADER_VERSION(2,1):
+ This->baseShader.limits.temporary = 12;
+ This->baseShader.limits.constant_bool = 16;
+ This->baseShader.limits.constant_int = 16;
+ This->baseShader.limits.address = 1;
+ This->baseShader.limits.packed_output = 0;
+ This->baseShader.limits.sampler = 0;
+ This->baseShader.limits.label = 16;
+ This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+ break;
+
+ case WINED3D_SHADER_VERSION(3,0):
+ This->baseShader.limits.temporary = 32;
+ This->baseShader.limits.constant_bool = 32;
+ This->baseShader.limits.constant_int = 32;
+ This->baseShader.limits.address = 1;
+ This->baseShader.limits.packed_output = 12;
+ This->baseShader.limits.sampler = 4;
+ This->baseShader.limits.label = 16; /* FIXME: 2048 */
+ /* DX10 cards on Windows advertise a d3d9 constant limit of 256 even though they are capable
+ * of supporting much more(GL drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
+ * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 shaders to 256.s
+ * use constant buffers */
+ This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+ break;
+
+ default:
+ This->baseShader.limits.temporary = 12;
+ This->baseShader.limits.constant_bool = 16;
+ This->baseShader.limits.constant_int = 16;
+ This->baseShader.limits.address = 1;
+ This->baseShader.limits.packed_output = 0;
+ This->baseShader.limits.sampler = 0;
+ This->baseShader.limits.label = 16;
+ This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+ FIXME("Unrecognized vertex shader version %u.%u\n",
+ This->baseShader.reg_maps.shader_version.major,
+ This->baseShader.reg_maps.shader_version.minor);
+ }
}
/* This is an internal function,
This->semantics_in[regnum].usage = usage;
This->semantics_in[regnum].usage_idx = usage_idx;
- This->semantics_in[regnum].reg.register_type = WINED3DSPR_INPUT;
- This->semantics_in[regnum].reg.register_idx = regnum;
+ This->semantics_in[regnum].reg.reg.type = WINED3DSPR_INPUT;
+ This->semantics_in[regnum].reg.reg.idx = regnum;
This->semantics_in[regnum].reg.write_mask = WINED3DSP_WRITEMASK_ALL;
This->semantics_in[regnum].reg.modifiers = 0;
This->semantics_in[regnum].reg.shift = 0;
- This->semantics_in[regnum].reg.has_rel_addr = FALSE;
- This->semantics_in[regnum].reg.addr_token = 0;
+ This->semantics_in[regnum].reg.reg.rel_addr = NULL;
}
static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) {
* shader is first used. The reason for this is that we need the vertex
* declaration the shader will be used with in order to determine if
* the data in a register is of type D3DCOLOR, and needs swizzling. */
-static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
-
+static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface,
+ const DWORD *pFunction, const struct wined3d_shader_signature *output_signature)
+{
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
+ const struct wined3d_shader_frontend *fe;
HRESULT hr;
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
TRACE("(%p) : pFunction %p\n", iface, pFunction);
+ fe = shader_select_frontend(*pFunction);
+ if (!fe)
+ {
+ FIXME("Unable to find frontend for shader.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ This->baseShader.frontend = fe;
+ This->baseShader.frontend_data = fe->shader_init(pFunction, output_signature);
+ if (!This->baseShader.frontend_data)
+ {
+ FIXME("Failed to initialize frontend.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
/* First pass: trace shader */
- if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
+ if (TRACE_ON(d3d_shader)) shader_trace_init(fe, This->baseShader.frontend_data, pFunction);
/* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF);
/* Second pass: figure out registers used, semantics, etc.. */
This->min_rel_offset = GL_LIMITS(vshader_constantsF);
This->max_rel_offset = 0;
- memset(reg_maps, 0, sizeof(shader_reg_maps));
- hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
- This->semantics_in, This->semantics_out, pFunction);
+ hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
+ reg_maps, This->semantics_in, This->semantics_out, pFunction,
+ GL_LIMITS(vshader_constantsF));
if (hr != WINED3D_OK) return hr;
vshader_set_limits(This);
- This->baseShader.shader_mode = deviceImpl->vs_selected_mode;
-
if(deviceImpl->vs_selected_mode == SHADER_ARB &&
(GLINFO_LOCATION).arb_vs_offset_limit &&
This->min_rel_offset <= This->max_rel_offset) {
<file>pixelshader.c</file>
<file>query.c</file>
<file>resource.c</file>
+ <file>shader_sm1.c</file>
+ <file>shader_sm4.c</file>
<file>state.c</file>
<file>stateblock.c</file>
<file>surface_base.c</file>
#define GL_DECR_WRAP_EXT 0x8508
#endif
+/* GL_ARB_half_float_vertex */
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex
+/* No _ARB, see extension spec */
+#define GL_HALF_FLOAT 0x140B
+#endif
/* GL_NV_half_float */
#ifndef GL_NV_half_float
#define GL_NV_half_float 1
#ifndef GL_APPLE_fence
#define GL_APPLE_fence 1
#define GL_DRAW_PIXELS_APPLE 0x8A0A
-#define GL_FENCE_APPLE 0x84F3
+#define GL_FENCE_APPLE 0x8A0B
#endif
typedef void (WINE_GLAPI * PGLFNGENFENCESAPPLEPROC) (GLsizei, GLuint *);
typedef void (WINE_GLAPI * PGLFNDELETEFENCESAPPLEPROC) (GLuint, const GLuint *);
ARB_VERTEX_BUFFER_OBJECT,
ARB_VERTEX_SHADER,
ARB_SHADER_OBJECTS,
+ ARB_SHADER_TEXTURE_LOD,
+ ARB_HALF_FLOAT_VERTEX,
/* EXT */
EXT_BLEND_COLOR,
EXT_BLEND_MINMAX,
UINT max_texture_size;
UINT max_texture3d_size;
float max_pointsize, max_pointsizemin;
+ UINT max_point_sprite_units;
UINT max_blends;
UINT max_anisotropy;
UINT max_glsl_varyings;
BOOL arb_vs_offset_limit;
BOOL set_texcoord_w;
+ DWORD reserved_glsl_constants;
BOOL supported[OPENGL_SUPPORTED_EXT_END + 1];
} WineD3D_GL_Info;
#undef USE_GL_FUNC
+struct driver_quirk {
+ BOOL (*match)(const WineD3D_GL_Info *gl_info);
+ void (*apply)(WineD3D_GL_Info *gl_info);
+ const char *description;
+};
+
#endif /* __WINE_WINED3D_GL */
*
* Copyright 2002-2003 The wine-d3d team
* Copyright 2002-2003 Raphael Junqueira
- * Copyright 2004 Jason Edmeades
+ * Copyright 2002-2003, 2004 Jason Edmeades
* Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
#include "wine/unicode.h"
#include "objbase.h"
-#include "wined3d_private_types.h"
#include "wine/wined3d.h"
#include "wined3d_gl.h"
#include "wine/list.h"
#define MAX_COMBINED_SAMPLERS (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS)
#define MAX_ACTIVE_LIGHTS 8
#define MAX_CLIPPLANES WINED3DMAXUSERCLIPPLANES
-#define MAX_LEVELS 256
-
-#define MAX_CONST_I 16
-#define MAX_CONST_B 16
/* Used for CreateStateBlock */
#define NUM_SAVEDPIXELSTATES_R 35
extern wined3d_settings_t wined3d_settings;
+typedef enum _WINED3DSAMPLER_TEXTURE_TYPE
+{
+ WINED3DSTT_UNKNOWN = 0,
+ WINED3DSTT_1D = 1,
+ WINED3DSTT_2D = 2,
+ WINED3DSTT_CUBE = 3,
+ WINED3DSTT_VOLUME = 4,
+} WINED3DSAMPLER_TEXTURE_TYPE;
+
+typedef enum _WINED3DSHADER_PARAM_REGISTER_TYPE
+{
+ WINED3DSPR_TEMP = 0,
+ WINED3DSPR_INPUT = 1,
+ WINED3DSPR_CONST = 2,
+ WINED3DSPR_ADDR = 3,
+ WINED3DSPR_TEXTURE = 3,
+ WINED3DSPR_RASTOUT = 4,
+ WINED3DSPR_ATTROUT = 5,
+ WINED3DSPR_TEXCRDOUT = 6,
+ WINED3DSPR_OUTPUT = 6,
+ WINED3DSPR_CONSTINT = 7,
+ WINED3DSPR_COLOROUT = 8,
+ WINED3DSPR_DEPTHOUT = 9,
+ WINED3DSPR_SAMPLER = 10,
+ WINED3DSPR_CONST2 = 11,
+ WINED3DSPR_CONST3 = 12,
+ WINED3DSPR_CONST4 = 13,
+ WINED3DSPR_CONSTBOOL = 14,
+ WINED3DSPR_LOOP = 15,
+ WINED3DSPR_TEMPFLOAT16 = 16,
+ WINED3DSPR_MISCTYPE = 17,
+ WINED3DSPR_LABEL = 18,
+ WINED3DSPR_PREDICATE = 19,
+ WINED3DSPR_IMMCONST,
+} WINED3DSHADER_PARAM_REGISTER_TYPE;
+
+enum wined3d_immconst_type
+{
+ WINED3D_IMMCONST_FLOAT,
+ WINED3D_IMMCONST_FLOAT4,
+};
+
+typedef enum _WINED3DVS_RASTOUT_OFFSETS
+{
+ WINED3DSRO_POSITION = 0,
+ WINED3DSRO_FOG = 1,
+ WINED3DSRO_POINT_SIZE = 2,
+} WINED3DVS_RASTOUT_OFFSETS;
+
+#define WINED3DSP_NOSWIZZLE (0 | (1 << 2) | (2 << 4) | (3 << 6))
+
+typedef enum _WINED3DSHADER_PARAM_SRCMOD_TYPE
+{
+ WINED3DSPSM_NONE = 0,
+ WINED3DSPSM_NEG = 1,
+ WINED3DSPSM_BIAS = 2,
+ WINED3DSPSM_BIASNEG = 3,
+ WINED3DSPSM_SIGN = 4,
+ WINED3DSPSM_SIGNNEG = 5,
+ WINED3DSPSM_COMP = 6,
+ WINED3DSPSM_X2 = 7,
+ WINED3DSPSM_X2NEG = 8,
+ WINED3DSPSM_DZ = 9,
+ WINED3DSPSM_DW = 10,
+ WINED3DSPSM_ABS = 11,
+ WINED3DSPSM_ABSNEG = 12,
+ WINED3DSPSM_NOT = 13,
+} WINED3DSHADER_PARAM_SRCMOD_TYPE;
+
+#define WINED3DSP_WRITEMASK_0 0x1 /* .x r */
+#define WINED3DSP_WRITEMASK_1 0x2 /* .y g */
+#define WINED3DSP_WRITEMASK_2 0x4 /* .z b */
+#define WINED3DSP_WRITEMASK_3 0x8 /* .w a */
+#define WINED3DSP_WRITEMASK_ALL 0xf /* all */
+
+typedef enum _WINED3DSHADER_PARAM_DSTMOD_TYPE
+{
+ WINED3DSPDM_NONE = 0,
+ WINED3DSPDM_SATURATE = 1,
+ WINED3DSPDM_PARTIALPRECISION = 2,
+ WINED3DSPDM_MSAMPCENTROID = 4,
+} WINED3DSHADER_PARAM_DSTMOD_TYPE;
+
+typedef enum _WINED3DSHADER_INSTRUCTION_OPCODE_TYPE
+{
+ WINED3DSIO_NOP = 0,
+ WINED3DSIO_MOV = 1,
+ WINED3DSIO_ADD = 2,
+ WINED3DSIO_SUB = 3,
+ WINED3DSIO_MAD = 4,
+ WINED3DSIO_MUL = 5,
+ WINED3DSIO_RCP = 6,
+ WINED3DSIO_RSQ = 7,
+ WINED3DSIO_DP3 = 8,
+ WINED3DSIO_DP4 = 9,
+ WINED3DSIO_MIN = 10,
+ WINED3DSIO_MAX = 11,
+ WINED3DSIO_SLT = 12,
+ WINED3DSIO_SGE = 13,
+ WINED3DSIO_EXP = 14,
+ WINED3DSIO_LOG = 15,
+ WINED3DSIO_LIT = 16,
+ WINED3DSIO_DST = 17,
+ WINED3DSIO_LRP = 18,
+ WINED3DSIO_FRC = 19,
+ WINED3DSIO_M4x4 = 20,
+ WINED3DSIO_M4x3 = 21,
+ WINED3DSIO_M3x4 = 22,
+ WINED3DSIO_M3x3 = 23,
+ WINED3DSIO_M3x2 = 24,
+ WINED3DSIO_CALL = 25,
+ WINED3DSIO_CALLNZ = 26,
+ WINED3DSIO_LOOP = 27,
+ WINED3DSIO_RET = 28,
+ WINED3DSIO_ENDLOOP = 29,
+ WINED3DSIO_LABEL = 30,
+ WINED3DSIO_DCL = 31,
+ WINED3DSIO_POW = 32,
+ WINED3DSIO_CRS = 33,
+ WINED3DSIO_SGN = 34,
+ WINED3DSIO_ABS = 35,
+ WINED3DSIO_NRM = 36,
+ WINED3DSIO_SINCOS = 37,
+ WINED3DSIO_REP = 38,
+ WINED3DSIO_ENDREP = 39,
+ WINED3DSIO_IF = 40,
+ WINED3DSIO_IFC = 41,
+ WINED3DSIO_ELSE = 42,
+ WINED3DSIO_ENDIF = 43,
+ WINED3DSIO_BREAK = 44,
+ WINED3DSIO_BREAKC = 45,
+ WINED3DSIO_MOVA = 46,
+ WINED3DSIO_DEFB = 47,
+ WINED3DSIO_DEFI = 48,
+
+ WINED3DSIO_TEXCOORD = 64,
+ WINED3DSIO_TEXKILL = 65,
+ WINED3DSIO_TEX = 66,
+ WINED3DSIO_TEXBEM = 67,
+ WINED3DSIO_TEXBEML = 68,
+ WINED3DSIO_TEXREG2AR = 69,
+ WINED3DSIO_TEXREG2GB = 70,
+ WINED3DSIO_TEXM3x2PAD = 71,
+ WINED3DSIO_TEXM3x2TEX = 72,
+ WINED3DSIO_TEXM3x3PAD = 73,
+ WINED3DSIO_TEXM3x3TEX = 74,
+ WINED3DSIO_TEXM3x3DIFF = 75,
+ WINED3DSIO_TEXM3x3SPEC = 76,
+ WINED3DSIO_TEXM3x3VSPEC = 77,
+ WINED3DSIO_EXPP = 78,
+ WINED3DSIO_LOGP = 79,
+ WINED3DSIO_CND = 80,
+ WINED3DSIO_DEF = 81,
+ WINED3DSIO_TEXREG2RGB = 82,
+ WINED3DSIO_TEXDP3TEX = 83,
+ WINED3DSIO_TEXM3x2DEPTH = 84,
+ WINED3DSIO_TEXDP3 = 85,
+ WINED3DSIO_TEXM3x3 = 86,
+ WINED3DSIO_TEXDEPTH = 87,
+ WINED3DSIO_CMP = 88,
+ WINED3DSIO_BEM = 89,
+ WINED3DSIO_DP2ADD = 90,
+ WINED3DSIO_DSX = 91,
+ WINED3DSIO_DSY = 92,
+ WINED3DSIO_TEXLDD = 93,
+ WINED3DSIO_SETP = 94,
+ WINED3DSIO_TEXLDL = 95,
+ WINED3DSIO_BREAKP = 96,
+
+ WINED3DSIO_PHASE = 0xfffd,
+ WINED3DSIO_COMMENT = 0xfffe,
+ WINED3DSIO_END = 0Xffff,
+} WINED3DSHADER_INSTRUCTION_OPCODE_TYPE;
+
+/* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */
+#define WINED3DSI_TEXLD_PROJECT 1
+#define WINED3DSI_TEXLD_BIAS 2
+
+typedef enum COMPARISON_TYPE
+{
+ COMPARISON_GT = 1,
+ COMPARISON_EQ = 2,
+ COMPARISON_GE = 3,
+ COMPARISON_LT = 4,
+ COMPARISON_NE = 5,
+ COMPARISON_LE = 6,
+} COMPARISON_TYPE;
+
+#define WINED3D_SM1_VS 0xfffe
+#define WINED3D_SM1_PS 0xffff
+#define WINED3D_SM4_PS 0x0000
+#define WINED3D_SM4_VS 0x0001
+#define WINED3D_SM4_GS 0x0002
+
+/* Shader version tokens, and shader end tokens */
+#define WINED3DPS_VERSION(major, minor) ((WINED3D_SM1_PS << 16) | ((major) << 8) | (minor))
+#define WINED3DVS_VERSION(major, minor) ((WINED3D_SM1_VS << 16) | ((major) << 8) | (minor))
+
/* Shader backends */
/* TODO: Make this dynamic, based on shader limits ? */
WINED3DSIH_TABLE_SIZE
};
+enum wined3d_shader_type
+{
+ WINED3D_SHADER_TYPE_PIXEL,
+ WINED3D_SHADER_TYPE_VERTEX,
+ WINED3D_SHADER_TYPE_GEOMETRY,
+};
+
+struct wined3d_shader_version
+{
+ enum wined3d_shader_type type;
+ BYTE major;
+ BYTE minor;
+};
+
+#define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor))
+
typedef struct shader_reg_maps
{
- DWORD shader_version;
+ struct wined3d_shader_version shader_version;
char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */
char temporary[MAX_REG_TEMP]; /* pixel, vertex */
char address[MAX_REG_ADDR]; /* vertex */
char packed_output[MAX_REG_OUTPUT]; /* vertex >= 3.0 */
char attributes[MAX_ATTRIBS]; /* vertex */
char labels[MAX_LABELS]; /* pixel, vertex */
+ DWORD *constf; /* pixel, vertex */
DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */
+ WORD integer_constants; /* MAX_CONST_I, 16 */
+ WORD boolean_constants; /* MAX_CONST_B, 16 */
- /* Sampler usage tokens
- * Use 0 as default (bit 31 is always 1 on a valid token) */
- DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
- char usesnrm, vpos, usesdsy;
+ char usesnrm, vpos, usesdsy, usestexldd;
char usesrelconstF;
/* Whether or not loops are used in this shader, and nesting depth */
} shader_reg_maps;
-typedef struct SHADER_OPCODE
+struct wined3d_shader_context
{
- unsigned int opcode;
- const char *name;
- char dst_token;
- CONST UINT num_params;
- enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
- DWORD min_version;
- DWORD max_version;
-} SHADER_OPCODE;
+ IWineD3DBaseShader *shader;
+ const struct shader_reg_maps *reg_maps;
+ SHADER_BUFFER *buffer;
+};
+
+struct wined3d_shader_register
+{
+ WINED3DSHADER_PARAM_REGISTER_TYPE type;
+ UINT idx;
+ const struct wined3d_shader_src_param *rel_addr;
+ enum wined3d_immconst_type immconst_type;
+ DWORD immconst_data[4];
+};
struct wined3d_shader_dst_param
{
- WINED3DSHADER_PARAM_REGISTER_TYPE register_type;
- UINT register_idx;
+ struct wined3d_shader_register reg;
DWORD write_mask;
DWORD modifiers;
DWORD shift;
- BOOL has_rel_addr;
- DWORD addr_token;
+};
+
+struct wined3d_shader_src_param
+{
+ struct wined3d_shader_register reg;
+ DWORD swizzle;
+ DWORD modifiers;
};
struct wined3d_shader_instruction
{
- IWineD3DBaseShader *shader;
- const shader_reg_maps *reg_maps;
+ const struct wined3d_shader_context *ctx;
enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
DWORD flags;
BOOL coissue;
DWORD predicate;
- DWORD src[4];
- DWORD src_addr[4];
- SHADER_BUFFER *buffer;
UINT dst_count;
const struct wined3d_shader_dst_param *dst;
UINT src_count;
+ const struct wined3d_shader_src_param *src;
};
struct wined3d_shader_semantic
{
WINED3DDECLUSAGE usage;
UINT usage_idx;
+ WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
struct wined3d_shader_dst_param reg;
};
+struct wined3d_shader_frontend
+{
+ void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature);
+ void (*shader_free)(void *data);
+ void (*shader_read_header)(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version);
+ void (*shader_read_opcode)(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins, UINT *param_size);
+ void (*shader_read_src_param)(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param,
+ struct wined3d_shader_src_param *src_rel_addr);
+ void (*shader_read_dst_param)(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
+ struct wined3d_shader_src_param *dst_rel_addr);
+ void (*shader_read_semantic)(const DWORD **ptr, struct wined3d_shader_semantic *semantic);
+ void (*shader_read_comment)(const DWORD **ptr, const char **comment);
+ BOOL (*shader_is_end)(void *data, const DWORD **ptr);
+};
+
+extern const struct wined3d_shader_frontend sm1_shader_frontend;
+extern const struct wined3d_shader_frontend sm4_shader_frontend;
+
typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
struct shader_caps {
HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
void (*shader_free_private)(IWineD3DDevice *iface);
BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
- GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args);
- GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args);
+ GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface,
+ SHADER_BUFFER *buffer, const struct ps_compile_args *args);
+ GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface,
+ SHADER_BUFFER *buffer, const struct vs_compile_args *args);
void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps);
BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
+ void (*shader_add_instruction_modifiers)(const struct wined3d_shader_instruction *ins);
} shader_backend_t;
extern const shader_backend_t glsl_shader_backend;
/* DirectX Device Limits */
/* --------------------- */
-#define MAX_LEVELS 256 /* Maximum number of mipmap levels. Guessed at 256 */
-
+#define MAX_MIP_LEVELS 32 /* Maximum number of mipmap levels. */
#define MAX_STREAMS 16 /* Maximum possible streams - used for fixed size arrays
See MaxStreams in MSDN under GetDeviceCaps */
#define HIGHEST_TRANSFORMSTATE WINED3DTS_WORLDMATRIX(255) /* Highest value in WINED3DTRANSFORMSTATETYPE */
*/
#define WINED3D_UNMAPPED_STAGE ~0U
+/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
+#define WINED3DCREATE_MULTITHREADED 0x00000004
+
struct IWineD3DDeviceImpl
{
/* IUnknown fields */
IWineD3DBaseTextureClass baseTexture;
/* IWineD3DTexture */
- IWineD3DSurface *surfaces[MAX_LEVELS];
+ IWineD3DSurface *surfaces[MAX_MIP_LEVELS];
UINT target;
BOOL cond_np2;
IWineD3DBaseTextureClass baseTexture;
/* IWineD3DCubeTexture */
- IWineD3DSurface *surfaces[6][MAX_LEVELS];
+ IWineD3DSurface *surfaces[6][MAX_MIP_LEVELS];
} IWineD3DCubeTextureImpl;
extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl;
IWineD3DBaseTextureClass baseTexture;
/* IWineD3DVolumeTexture */
- IWineD3DVolume *volumes[MAX_LEVELS];
+ IWineD3DVolume *volumes[MAX_MIP_LEVELS];
} IWineD3DVolumeTextureImpl;
extern const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl;
CONVERT_V16U16,
CONVERT_A4L4,
CONVERT_G16R16,
+ CONVERT_R16G16F,
+ CONVERT_R32G32F,
} CONVERT_TYPES;
HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);
/* Math utils */
void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);
UINT wined3d_log2i(UINT32 x);
+unsigned int count_bits(unsigned int mask);
typedef struct local_constant {
struct list entry;
DWORD value[4];
} local_constant;
-/* Undocumented opcode controls */
-#define INST_CONTROLS_SHIFT 16
-#define INST_CONTROLS_MASK 0x00ff0000
-
-typedef enum COMPARISON_TYPE {
- COMPARISON_GT = 1,
- COMPARISON_EQ = 2,
- COMPARISON_GE = 3,
- COMPARISON_LT = 4,
- COMPARISON_NE = 5,
- COMPARISON_LE = 6
-} COMPARISON_TYPE;
-
typedef struct SHADER_LIMITS {
unsigned int temporary;
unsigned int texcoord;
const char* fmt, ...) PRINTF_ATTR(2,3);
int shader_vaddline(SHADER_BUFFER *buffer, const char *fmt, va_list args);
-const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *shader_ins, DWORD shader_version, DWORD code);
-
/* Vertex shader utility functions */
extern BOOL vshader_get_input(
IWineD3DVertexShader* iface,
extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object);
-/* GLSL helper functions */
-extern void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins);
-
/*****************************************************************************
* IDirect3DBaseShader implementation structure
*/
LONG ref;
SHADER_LIMITS limits;
SHADER_PARSE_STATE parse_state;
- CONST SHADER_OPCODE *shader_ins;
DWORD *function;
UINT functionLength;
UINT cur_loop_depth, cur_loop_regno;
BOOL load_local_constsF;
- BOOL uses_bool_consts, uses_int_consts;
-
- /* Type of shader backend */
- int shader_mode;
+ const struct wined3d_shader_frontend *frontend;
+ void *frontend_data;
/* Programs this shader is linked with */
struct list linked_programs;
void shader_buffer_init(struct SHADER_BUFFER *buffer);
void shader_buffer_free(struct SHADER_BUFFER *buffer);
void shader_cleanup(IWineD3DBaseShader *iface);
-HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
- struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out,
- const DWORD *byte_code);
-void shader_init(struct IWineD3DBaseShaderClass *shader,
- IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
-void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table);
-
-extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
+void shader_dump_src_param(const struct wined3d_shader_src_param *param,
+ const struct wined3d_shader_version *shader_version);
+void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
+ const struct wined3d_shader_version *shader_version);
+void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
const shader_reg_maps *reg_maps, const DWORD *pFunction);
-
-static inline int shader_get_regtype(const DWORD param) {
- return (((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) |
- ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2));
-}
-
-static inline int shader_get_writemask(const DWORD param) {
- return param & WINED3DSP_WRITEMASK_ALL;
-}
-
-static inline BOOL shader_is_pshader_version(DWORD token) {
- return 0xFFFF0000 == (token & 0xFFFF0000);
-}
-
-static inline BOOL shader_is_vshader_version(DWORD token) {
- return 0xFFFE0000 == (token & 0xFFFF0000);
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
+ struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
+ struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size);
+void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device);
+const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token);
+void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction);
+
+static inline BOOL shader_is_pshader_version(enum wined3d_shader_type type)
+{
+ return type == WINED3D_SHADER_TYPE_PIXEL;
}
-static inline BOOL shader_is_comment(DWORD token) {
- return WINED3DSIO_COMMENT == (token & WINED3DSI_OPCODE_MASK);
+static inline BOOL shader_is_vshader_version(enum wined3d_shader_type type)
+{
+ return type == WINED3D_SHADER_TYPE_VERTEX;
}
-static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx)
+static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
{
- switch (register_type)
+ switch (reg->type)
{
case WINED3DSPR_RASTOUT:
/* oFog & oPts */
- if (register_idx != 0) return TRUE;
+ if (reg->idx != 0) return TRUE;
/* oPos */
return FALSE;
return TRUE;
case WINED3DSPR_MISCTYPE:
- switch(register_idx)
+ switch(reg->idx)
{
case 0: /* vPos */
return FALSE;
return FALSE;
}
+ case WINED3DSPR_IMMCONST:
+ switch(reg->immconst_type)
+ {
+ case WINED3D_IMMCONST_FLOAT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
default:
return FALSE;
}
const struct vs_compile_args *cur_args;
} IWineD3DVertexShaderImpl;
-extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[];
extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args);
const struct ps_compile_args *cur_args;
} IWineD3DPixelShaderImpl;
-extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args);
void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);
* Pixel format management
*/
+/* WineD3D pixel format flags */
+#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x1
+#define WINED3DFMT_FLAG_FILTERING 0x2
+#define WINED3DFMT_FLAG_DEPTH 0x4
+#define WINED3DFMT_FLAG_STENCIL 0x8
+#define WINED3DFMT_FLAG_RENDERTARGET 0x10
+#define WINED3DFMT_FLAG_FOURCC 0x20
+
struct GlPixelFormatDesc
{
WINED3DFORMAT format;
+++ /dev/null
-/*
- * Direct3D wine internal header: D3D equivalent types
- *
- * Copyright 2002-2003 Jason Edmeades
- * Copyright 2002-2003 Raphael Junqueira
- * Copyright 2005 Oliver Stieber
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef __WINE_WINED3D_TYPES_INTERNAL_H
-#define __WINE_WINED3D_TYPES_INTERNAL_H
-
-/* WineD3D pixel format flags */
-#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x1
-#define WINED3DFMT_FLAG_FILTERING 0x2
-#define WINED3DFMT_FLAG_DEPTH 0x4
-#define WINED3DFMT_FLAG_STENCIL 0x8
-#define WINED3DFMT_FLAG_RENDERTARGET 0x10
-#define WINED3DFMT_FLAG_FOURCC 0x20
-
-/** DCL usage masks **/
-#define WINED3DSP_DCL_USAGE_SHIFT 0
-#define WINED3DSP_DCL_USAGE_MASK 0x0000000f
-#define WINED3DSP_DCL_USAGEINDEX_SHIFT 16
-#define WINED3DSP_DCL_USAGEINDEX_MASK 0x000f0000
-
-/** DCL sampler texture type **/
-#define WINED3DSP_TEXTURETYPE_SHIFT 27
-#define WINED3DSP_TEXTURETYPE_MASK 0x78000000
-
-typedef enum _WINED3DSAMPLER_TEXTURE_TYPE {
- WINED3DSTT_UNKNOWN = 0 << WINED3DSP_TEXTURETYPE_SHIFT,
- WINED3DSTT_1D = 1 << WINED3DSP_TEXTURETYPE_SHIFT,
- WINED3DSTT_2D = 2 << WINED3DSP_TEXTURETYPE_SHIFT,
- WINED3DSTT_CUBE = 3 << WINED3DSP_TEXTURETYPE_SHIFT,
- WINED3DSTT_VOLUME = 4 << WINED3DSP_TEXTURETYPE_SHIFT,
-
- WINED3DSTT_FORCE_DWORD = 0x7FFFFFFF
-} WINED3DSAMPLER_TEXTURE_TYPE;
-
-/** Register number mask **/
-#define WINED3DSP_REGNUM_MASK 0x000007FF
-
-/** Register type masks **/
-#define WINED3DSP_REGTYPE_SHIFT 28
-#define WINED3DSP_REGTYPE_SHIFT2 8
-#define WINED3DSP_REGTYPE_MASK (0x7 << WINED3DSP_REGTYPE_SHIFT)
-#define WINED3DSP_REGTYPE_MASK2 0x00001800
-
-/** Register types **/
-typedef enum _WINED3DSHADER_PARAM_REGISTER_TYPE {
- WINED3DSPR_TEMP = 0,
- WINED3DSPR_INPUT = 1,
- WINED3DSPR_CONST = 2,
- WINED3DSPR_ADDR = 3,
- WINED3DSPR_TEXTURE = 3,
- WINED3DSPR_RASTOUT = 4,
- WINED3DSPR_ATTROUT = 5,
- WINED3DSPR_TEXCRDOUT = 6,
- WINED3DSPR_OUTPUT = 6,
- WINED3DSPR_CONSTINT = 7,
- WINED3DSPR_COLOROUT = 8,
- WINED3DSPR_DEPTHOUT = 9,
- WINED3DSPR_SAMPLER = 10,
- WINED3DSPR_CONST2 = 11,
- WINED3DSPR_CONST3 = 12,
- WINED3DSPR_CONST4 = 13,
- WINED3DSPR_CONSTBOOL = 14,
- WINED3DSPR_LOOP = 15,
- WINED3DSPR_TEMPFLOAT16 = 16,
- WINED3DSPR_MISCTYPE = 17,
- WINED3DSPR_LABEL = 18,
- WINED3DSPR_PREDICATE = 19,
-
- WINED3DSPR_FORCE_DWORD = 0x7FFFFFFF
-} WINED3DSHADER_PARAM_REGISTER_TYPE;
-
-/* RASTOUT register offsets */
-typedef enum _WINED3DVS_RASTOUT_OFFSETS {
- WINED3DSRO_POSITION = 0,
- WINED3DSRO_FOG = 1,
- WINED3DSRO_POINT_SIZE = 2,
-
- WINED3DSRO_FORCE_DWORD = 0x7FFFFFFF
-} WINED3DVS_RASTOUT_OFFSETS;
-
-/** Source register modifiers **/
-#define WINED3DVS_SWIZZLE_SHIFT 16
-#define WINED3DVS_SWIZZLE_MASK (0xFF << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DSP_SWIZZLE_SHIFT 16
-#define WINED3DSP_SWIZZLE_MASK (0xFF << WINED3DSP_SWIZZLE_SHIFT)
-
-#define WINED3DVS_X_X (0 << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DVS_X_Y (1 << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DVS_X_Z (2 << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DVS_X_W (3 << WINED3DVS_SWIZZLE_SHIFT)
-
-#define WINED3DVS_Y_X (0 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-#define WINED3DVS_Y_Y (1 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-#define WINED3DVS_Y_Z (2 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-#define WINED3DVS_Y_W (3 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-
-#define WINED3DVS_Z_X (0 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-#define WINED3DVS_Z_Y (1 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-#define WINED3DVS_Z_Z (2 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-#define WINED3DVS_Z_W (3 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-
-#define WINED3DVS_W_X (0 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-#define WINED3DVS_W_Y (1 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-#define WINED3DVS_W_Z (2 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-#define WINED3DVS_W_W (3 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-
-#define WINED3DVS_NOSWIZZLE (WINED3DVS_X_X | WINED3DVS_Y_Y | WINED3DVS_Z_Z | WINED3DVS_W_W)
-
-#define WINED3DSP_NOSWIZZLE \
- ((0 << (WINED3DSP_SWIZZLE_SHIFT + 0)) | (1 << (WINED3DSP_SWIZZLE_SHIFT + 2)) | \
- (2 << (WINED3DSP_SWIZZLE_SHIFT + 4)) | (3 << (WINED3DSP_SWIZZLE_SHIFT + 6)))
-
-#define WINED3DSP_SRCMOD_SHIFT 24
-#define WINED3DSP_SRCMOD_MASK (0xF << WINED3DSP_SRCMOD_SHIFT)
-
-typedef enum _WINED3DSHADER_PARAM_SRCMOD_TYPE {
- WINED3DSPSM_NONE = 0 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_NEG = 1 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_BIAS = 2 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_BIASNEG = 3 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_SIGN = 4 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_SIGNNEG = 5 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_COMP = 6 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_X2 = 7 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_X2NEG = 8 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_DZ = 9 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_DW = 10 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_ABS = 11 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_ABSNEG = 12 << WINED3DSP_SRCMOD_SHIFT,
- WINED3DSPSM_NOT = 13 << WINED3DSP_SRCMOD_SHIFT,
-
- WINED3DSPSM_FORCE_DWORD = 0x7FFFFFFF
-} WINED3DSHADER_PARAM_SRCMOD_TYPE;
-
-/** Destination register modifiers **/
-#define WINED3DSP_WRITEMASK_0 0x00010000 /* .x r */
-#define WINED3DSP_WRITEMASK_1 0x00020000 /* .y g */
-#define WINED3DSP_WRITEMASK_2 0x00040000 /* .z b */
-#define WINED3DSP_WRITEMASK_3 0x00080000 /* .w a */
-#define WINED3DSP_WRITEMASK_ALL 0x000F0000 /* all */
-
-#define WINED3DSP_DSTMOD_SHIFT 20
-#define WINED3DSP_DSTMOD_MASK (0xF << WINED3DSP_DSTMOD_SHIFT)
-
-typedef enum _WINED3DSHADER_PARAM_DSTMOD_TYPE {
- WINED3DSPDM_NONE = 0 << WINED3DSP_DSTMOD_SHIFT,
- WINED3DSPDM_SATURATE = 1 << WINED3DSP_DSTMOD_SHIFT,
- WINED3DSPDM_PARTIALPRECISION = 2 << WINED3DSP_DSTMOD_SHIFT,
- WINED3DSPDM_MSAMPCENTROID = 4 << WINED3DSP_DSTMOD_SHIFT,
-
- WINED3DSPDM_FORCE_DWORD = 0x7FFFFFFF
-} WINED3DSHADER_PARAM_DSTMOD_TYPE;
-
-#define WINED3DSP_DSTSHIFT_SHIFT 24
-#define WINED3DSP_DSTSHIFT_MASK (0xF << WINED3DSP_DSTSHIFT_SHIFT)
-
-/** Register addressing modes **/
-#define WINED3DSHADER_ADDRESSMODE_SHIFT 13
-#define WINED3DSHADER_ADDRESSMODE_MASK (1 << WINED3DSHADER_ADDRESSMODE_SHIFT)
-
-typedef enum _WINED3DSHADER_ADDRESSMODE_TYPE {
- WINED3DSHADER_ADDRMODE_ABSOLUTE = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT,
- WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
-
- WINED3DSHADER_ADDRMODE_FORCE_DWORD = 0x7FFFFFFF
-} WINED3DSHADER_ADDRESSMODE_TYPE;
-
-/** Opcode types */
-typedef enum _WINED3DSHADER_INSTRUCTION_OPCODE_TYPE {
- WINED3DSIO_NOP = 0,
- WINED3DSIO_MOV = 1,
- WINED3DSIO_ADD = 2,
- WINED3DSIO_SUB = 3,
- WINED3DSIO_MAD = 4,
- WINED3DSIO_MUL = 5,
- WINED3DSIO_RCP = 6,
- WINED3DSIO_RSQ = 7,
- WINED3DSIO_DP3 = 8,
- WINED3DSIO_DP4 = 9,
- WINED3DSIO_MIN = 10,
- WINED3DSIO_MAX = 11,
- WINED3DSIO_SLT = 12,
- WINED3DSIO_SGE = 13,
- WINED3DSIO_EXP = 14,
- WINED3DSIO_LOG = 15,
- WINED3DSIO_LIT = 16,
- WINED3DSIO_DST = 17,
- WINED3DSIO_LRP = 18,
- WINED3DSIO_FRC = 19,
- WINED3DSIO_M4x4 = 20,
- WINED3DSIO_M4x3 = 21,
- WINED3DSIO_M3x4 = 22,
- WINED3DSIO_M3x3 = 23,
- WINED3DSIO_M3x2 = 24,
- WINED3DSIO_CALL = 25,
- WINED3DSIO_CALLNZ = 26,
- WINED3DSIO_LOOP = 27,
- WINED3DSIO_RET = 28,
- WINED3DSIO_ENDLOOP = 29,
- WINED3DSIO_LABEL = 30,
- WINED3DSIO_DCL = 31,
- WINED3DSIO_POW = 32,
- WINED3DSIO_CRS = 33,
- WINED3DSIO_SGN = 34,
- WINED3DSIO_ABS = 35,
- WINED3DSIO_NRM = 36,
- WINED3DSIO_SINCOS = 37,
- WINED3DSIO_REP = 38,
- WINED3DSIO_ENDREP = 39,
- WINED3DSIO_IF = 40,
- WINED3DSIO_IFC = 41,
- WINED3DSIO_ELSE = 42,
- WINED3DSIO_ENDIF = 43,
- WINED3DSIO_BREAK = 44,
- WINED3DSIO_BREAKC = 45,
- WINED3DSIO_MOVA = 46,
- WINED3DSIO_DEFB = 47,
- WINED3DSIO_DEFI = 48,
-
- WINED3DSIO_TEXCOORD = 64,
- WINED3DSIO_TEXKILL = 65,
- WINED3DSIO_TEX = 66,
- WINED3DSIO_TEXBEM = 67,
- WINED3DSIO_TEXBEML = 68,
- WINED3DSIO_TEXREG2AR = 69,
- WINED3DSIO_TEXREG2GB = 70,
- WINED3DSIO_TEXM3x2PAD = 71,
- WINED3DSIO_TEXM3x2TEX = 72,
- WINED3DSIO_TEXM3x3PAD = 73,
- WINED3DSIO_TEXM3x3TEX = 74,
- WINED3DSIO_TEXM3x3DIFF = 75,
- WINED3DSIO_TEXM3x3SPEC = 76,
- WINED3DSIO_TEXM3x3VSPEC = 77,
- WINED3DSIO_EXPP = 78,
- WINED3DSIO_LOGP = 79,
- WINED3DSIO_CND = 80,
- WINED3DSIO_DEF = 81,
- WINED3DSIO_TEXREG2RGB = 82,
- WINED3DSIO_TEXDP3TEX = 83,
- WINED3DSIO_TEXM3x2DEPTH = 84,
- WINED3DSIO_TEXDP3 = 85,
- WINED3DSIO_TEXM3x3 = 86,
- WINED3DSIO_TEXDEPTH = 87,
- WINED3DSIO_CMP = 88,
- WINED3DSIO_BEM = 89,
- WINED3DSIO_DP2ADD = 90,
- WINED3DSIO_DSX = 91,
- WINED3DSIO_DSY = 92,
- WINED3DSIO_TEXLDD = 93,
- WINED3DSIO_SETP = 94,
- WINED3DSIO_TEXLDL = 95,
- WINED3DSIO_BREAKP = 96,
-
- WINED3DSIO_PHASE = 0xFFFD,
- WINED3DSIO_COMMENT = 0xFFFE,
- WINED3DSIO_END = 0XFFFF,
-
- WINED3DSIO_FORCE_DWORD = 0X7FFFFFFF /** for 32-bit alignment */
-} WINED3DSHADER_INSTRUCTION_OPCODE_TYPE;
-
-/** opcode-related masks **/
-
-#define WINED3D_OPCODESPECIFICCONTROL_MASK 0x00ff0000
-#define WINED3D_OPCODESPECIFICCONTROL_SHIFT 16
-
-#define WINED3DSI_OPCODE_MASK 0x0000FFFF
-#define WINED3DSI_INSTLENGTH_MASK 0x0F000000
-#define WINED3DSI_INSTLENGTH_SHIFT 24
-
-#define WINED3DSI_COISSUE 0x40000000
-
-#define WINED3DSI_COMMENTSIZE_SHIFT 16
-#define WINED3DSI_COMMENTSIZE_MASK (0x7FFF << WINED3DSI_COMMENTSIZE_SHIFT)
-#define WINED3DSHADER_COMMENT(commentSize) \
- ((((commentSize) << WINED3DSI_COMMENTSIZE_SHIFT) & WINED3DSI_COMMENTSIZE_MASK) | WINED3DSIO_COMMENT)
-
-#define WINED3DSHADER_INSTRUCTION_PREDICATED (1 << 28)
-
-/* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */
-#define WINED3DSI_TEXLD_PROJECT 0x00010000
-#define WINED3DSI_TEXLD_BIAS 0x00020000
-
-/** Shader version tokens, and shader end tokens **/
-
-#define WINED3DPS_VERSION(major, minor) (0xFFFF0000 | ((major) << 8) | (minor))
-#define WINED3DVS_VERSION(major, minor) (0xFFFE0000 | ((major) << 8) | (minor))
-#define WINED3DSHADER_VERSION_MAJOR(version) (((version) >> 8) & 0xFF)
-#define WINED3DSHADER_VERSION_MINOR(version) (((version) >> 0) & 0xFF)
-#define WINED3DPS_END() 0x0000FFFF
-#define WINED3DVS_END() 0x0000FFFF
-
-/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
-#define WINED3DCREATE_MULTITHREADED 0x00000004
-
-#endif
SURFACE_GDI, /* User surface. No 3D, DirectDraw rendering with GDI */
} WINED3DSURFTYPE;
+enum wined3d_sysval_semantic
+{
+ WINED3D_SV_DEPTH = 0xffffffff,
+ WINED3D_SV_TARGET0 = 0,
+ WINED3D_SV_TARGET1 = 1,
+ WINED3D_SV_TARGET2 = 2,
+ WINED3D_SV_TARGET3 = 3,
+ WINED3D_SV_TARGET4 = 4,
+ WINED3D_SV_TARGET5 = 5,
+ WINED3D_SV_TARGET6 = 6,
+ WINED3D_SV_TARGET7 = 7,
+};
+
const UINT WINED3DCOLORWRITEENABLE_RED = (1<<0);
const UINT WINED3DCOLORWRITEENABLE_GREEN = (1<<1);
const UINT WINED3DCOLORWRITEENABLE_BLUE = (1<<2);
UINT misc_flags;
};
+struct wined3d_shader_signature_element
+{
+ const char *semantic_name;
+ UINT semantic_idx;
+ enum wined3d_sysval_semantic sysval_semantic;
+ DWORD component_type;
+ UINT register_idx;
+ DWORD mask;
+};
+
+struct wined3d_shader_signature
+{
+ UINT element_count;
+ struct wined3d_shader_signature_element *elements;
+ char *string_data;
+};
+
interface IWineD3DResource;
interface IWineD3DSurface;
interface IWineD3DVolume;
);
HRESULT EnumAdapterModes(
[in] UINT adapter_idx,
- [in] UINT mode_idx,
[in] WINED3DFORMAT format,
+ [in] UINT mode_idx,
[out] WINED3DDISPLAYMODE *mode
);
HRESULT GetAdapterDisplayMode(
interface IWineD3DBaseShader : IWineD3DBase
{
HRESULT SetFunction(
- [in] const DWORD *function
+ [in] const DWORD *function,
+ [in] const struct wined3d_shader_signature *output_signature
);
}
[in] DWORD fvf,
[in] WINED3DPOOL pool,
[out] IWineD3DBuffer **vertex_buffer,
- [in] HANDLE *shared_handle,
[in] IUnknown *parent
);
HRESULT CreateIndexBuffer(
[in] DWORD usage,
[in] WINED3DPOOL pool,
[out] IWineD3DBuffer **index_buffer,
- [in] HANDLE *shared_handle,
[in] IUnknown *parent
);
HRESULT CreateStateBlock(
[in] WINED3DPOOL pool,
[in] WINED3DMULTISAMPLE_TYPE multisample_type,
[in] DWORD multisample_quality,
- [in] HANDLE *shared_handle,
[in] WINED3DSURFTYPE surface_type,
[in] IUnknown *parent
);
[in] WINED3DFORMAT format,
[in] WINED3DPOOL pool,
[out] IWineD3DTexture **texture,
- [in] HANDLE *shared_handle,
[in] IUnknown *parent
);
HRESULT CreateVolumeTexture(
[in] WINED3DFORMAT format,
[in] WINED3DPOOL pool,
[out] IWineD3DVolumeTexture **texture,
- [in] HANDLE *shared_handle,
[in] IUnknown *parent
);
HRESULT CreateVolume(
[in] WINED3DFORMAT format,
[in] WINED3DPOOL pool,
[out] IWineD3DVolume **volume,
- [in] HANDLE *shared_handle,
[in] IUnknown *parent
);
HRESULT CreateCubeTexture(
[in] WINED3DFORMAT format,
[in] WINED3DPOOL pool,
[out] IWineD3DCubeTexture **texture,
- [in] HANDLE *shared_handle,
[in] IUnknown *parent
);
HRESULT CreateQuery(
);
HRESULT CreatePixelShader(
[in] const DWORD *function,
+ [in] const struct wined3d_shader_signature *output_signature,
[out] IWineD3DPixelShader **shader,
[in] IUnknown *parent
);