📄 device.c
字号:
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVolumeTextureImpl *object;
unsigned int i;
UINT tmpW;
UINT tmpH;
UINT tmpD;
/* TODO: It should only be possible to create textures for formats
that are reported as supported */
if (WINED3DFMT_UNKNOWN >= Format) {
WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
return WINED3DERR_INVALIDCALL;
}
D3DCREATERESOURCEOBJECTINSTANCE(object, VolumeTexture, WINED3DRTYPE_VOLUMETEXTURE, 0);
D3DINITIALIZEBASETEXTURE(object->baseTexture);
TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
object->width = Width;
object->height = Height;
object->depth = Depth;
/* Calculate levels for mip mapping */
if (Levels == 0) {
object->baseTexture.levels++;
tmpW = Width;
tmpH = Height;
tmpD = Depth;
while (tmpW > 1 || tmpH > 1 || tmpD > 1) {
tmpW = max(1, tmpW >> 1);
tmpH = max(1, tmpH >> 1);
tmpD = max(1, tmpD >> 1);
object->baseTexture.levels++;
}
TRACE("Calculated levels = %d\n", object->baseTexture.levels);
}
/* Generate all the surfaces */
tmpW = Width;
tmpH = Height;
tmpD = Depth;
for (i = 0; i < object->baseTexture.levels; i++)
{
HRESULT hr;
/* Create the volume */
hr = D3DCB_CreateVolume(This->parent, parent, tmpW, tmpH, tmpD, Format, Pool, Usage,
(IWineD3DVolume **)&object->volumes[i], pSharedHandle);
if(FAILED(hr)) {
ERR("Creating a volume for the volume texture failed(%08x)\n", hr);
IWineD3DVolumeTexture_Release((IWineD3DVolumeTexture *) object);
*ppVolumeTexture = NULL;
return hr;
}
/* Set its container to this object */
IWineD3DVolume_SetContainer(object->volumes[i], (IWineD3DBase *)object);
/* calcualte the next mipmap level */
tmpW = max(1, tmpW >> 1);
tmpH = max(1, tmpH >> 1);
tmpD = max(1, tmpD >> 1);
}
*ppVolumeTexture = (IWineD3DVolumeTexture *) object;
TRACE("(%p) : Created volume texture %p\n", This, object);
return WINED3D_OK;
}
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) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVolumeImpl *object; /** NOTE: impl ref allowed since this is a create function **/
const StaticPixelFormatDesc *formatDesc = getFormatDescEntry(Format, NULL, NULL);
D3DCREATERESOURCEOBJECTINSTANCE(object, Volume, WINED3DRTYPE_VOLUME, ((Width * formatDesc->bpp) * Height * Depth))
TRACE("(%p) : W(%d) H(%d) D(%d), Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
Depth, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
object->currentDesc.Width = Width;
object->currentDesc.Height = Height;
object->currentDesc.Depth = Depth;
object->bytesPerPixel = formatDesc->bpp;
/** Note: Volume textures cannot be dxtn, hence no need to check here **/
object->lockable = TRUE;
object->locked = FALSE;
memset(&object->lockedBox, 0, sizeof(WINED3DBOX));
object->dirty = TRUE;
return IWineD3DVolume_AddDirtyBox((IWineD3DVolume *) object, NULL);
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface, UINT EdgeLength,
UINT Levels, DWORD Usage,
WINED3DFORMAT Format, WINED3DPOOL Pool,
IWineD3DCubeTexture **ppCubeTexture,
HANDLE *pSharedHandle, IUnknown *parent,
D3DCB_CREATESURFACEFN D3DCB_CreateSurface) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/
unsigned int i, j;
UINT tmpW;
HRESULT hr;
unsigned int pow2EdgeLength = EdgeLength;
/* TODO: It should only be possible to create textures for formats
that are reported as supported */
if (WINED3DFMT_UNKNOWN >= Format) {
WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
return WINED3DERR_INVALIDCALL;
}
if (!GL_SUPPORT(ARB_TEXTURE_CUBE_MAP) && Pool != WINED3DPOOL_SCRATCH) {
WARN("(%p) : Tried to create not supported cube texture\n", This);
return WINED3DERR_INVALIDCALL;
}
D3DCREATERESOURCEOBJECTINSTANCE(object, CubeTexture, WINED3DRTYPE_CUBETEXTURE, 0);
D3DINITIALIZEBASETEXTURE(object->baseTexture);
TRACE("(%p) Create Cube Texture\n", This);
/** Non-power2 support **/
/* Find the nearest pow2 match */
pow2EdgeLength = 1;
while (pow2EdgeLength < EdgeLength) pow2EdgeLength <<= 1;
object->edgeLength = EdgeLength;
/* TODO: support for native non-power 2 */
/* Precalculated scaling for 'faked' non power of two texture coords */
object->pow2scalingFactor = ((float)EdgeLength) / ((float)pow2EdgeLength);
/* Calculate levels for mip mapping */
if (Levels == 0) {
object->baseTexture.levels++;
tmpW = EdgeLength;
while (tmpW > 1) {
tmpW = max(1, tmpW >> 1);
object->baseTexture.levels++;
}
TRACE("Calculated levels = %d\n", object->baseTexture.levels);
}
/* Generate all the surfaces */
tmpW = EdgeLength;
for (i = 0; i < object->baseTexture.levels; i++) {
/* Create the 6 faces */
for (j = 0; j < 6; j++) {
hr=D3DCB_CreateSurface(This->parent, parent, tmpW, tmpW, Format, Usage, Pool,
i /* Level */, j, &object->surfaces[j][i],pSharedHandle);
if(hr!= WINED3D_OK) {
/* clean up */
int k;
int l;
for (l = 0; l < j; l++) {
IWineD3DSurface_Release(object->surfaces[j][i]);
}
for (k = 0; k < i; k++) {
for (l = 0; l < 6; l++) {
IWineD3DSurface_Release(object->surfaces[l][j]);
}
}
FIXME("(%p) Failed to create surface\n",object);
HeapFree(GetProcessHeap(),0,object);
*ppCubeTexture = NULL;
return hr;
}
IWineD3DSurface_SetContainer(object->surfaces[j][i], (IWineD3DBase *)object);
TRACE("Created surface level %d @ %p,\n", i, object->surfaces[j][i]);
}
tmpW = max(1, tmpW >> 1);
}
TRACE("(%p) : Created Cube Texture %p\n", This, object);
*ppCubeTexture = (IWineD3DCubeTexture *) object;
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINED3DQUERYTYPE Type, IWineD3DQuery **ppQuery, IUnknown* parent) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DQueryImpl *object; /*NOTE: impl ref allowed since this is a create function */
HRESULT hr = WINED3DERR_NOTAVAILABLE;
/* Just a check to see if we support this type of query */
switch(Type) {
case WINED3DQUERYTYPE_OCCLUSION:
TRACE("(%p) occlusion query\n", This);
if (GL_SUPPORT(ARB_OCCLUSION_QUERY))
hr = WINED3D_OK;
else
WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY/NV_OCCLUSION_QUERY\n");
break;
case WINED3DQUERYTYPE_EVENT:
if(!(GL_SUPPORT(NV_FENCE) || GL_SUPPORT(APPLE_FENCE) )) {
/* Half-Life 2 needs this query. It does not render the main menu correctly otherwise
* Pretend to support it, faking this query does not do much harm except potentially lowering performance
*/
FIXME("(%p) Event query: Unimplemented, but pretending to be supported\n", This);
}
hr = WINED3D_OK;
break;
case WINED3DQUERYTYPE_VCACHE:
case WINED3DQUERYTYPE_RESOURCEMANAGER:
case WINED3DQUERYTYPE_VERTEXSTATS:
case WINED3DQUERYTYPE_TIMESTAMP:
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
case WINED3DQUERYTYPE_PIPELINETIMINGS:
case WINED3DQUERYTYPE_INTERFACETIMINGS:
case WINED3DQUERYTYPE_VERTEXTIMINGS:
case WINED3DQUERYTYPE_PIXELTIMINGS:
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
case WINED3DQUERYTYPE_CACHEUTILIZATION:
default:
FIXME("(%p) Unhandled query type %d\n", This, Type);
}
if(NULL == ppQuery || hr != WINED3D_OK) {
return hr;
}
D3DCREATEOBJECTINSTANCE(object, Query)
object->type = Type;
/* allocated the 'extended' data based on the type of query requested */
switch(Type){
case WINED3DQUERYTYPE_OCCLUSION:
if(GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
TRACE("(%p) Allocating data for an occlusion query\n", This);
object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryOcclusionData));
GL_EXTCALL(glGenQueriesARB(1, &((WineQueryOcclusionData *)(object->extendedData))->queryId));
break;
}
case WINED3DQUERYTYPE_EVENT:
/* TODO: GL_APPLE_fence */
if(GL_SUPPORT(APPLE_FENCE)) {
object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
GL_EXTCALL(glGenFencesAPPLE(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
checkGLcall("glGenFencesAPPLE");
} else if(GL_SUPPORT(NV_FENCE)) {
object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
GL_EXTCALL(glGenFencesNV(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
checkGLcall("glGenFencesNV");
}
break;
case WINED3DQUERYTYPE_VCACHE:
case WINED3DQUERYTYPE_RESOURCEMANAGER:
case WINED3DQUERYTYPE_VERTEXSTATS:
case WINED3DQUERYTYPE_TIMESTAMP:
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
case WINED3DQUERYTYPE_PIPELINETIMINGS:
case WINED3DQUERYTYPE_INTERFACETIMINGS:
case WINED3DQUERYTYPE_VERTEXTIMINGS:
case WINED3DQUERYTYPE_PIXELTIMINGS:
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
case WINED3DQUERYTYPE_CACHEUTILIZATION:
default:
object->extendedData = 0;
FIXME("(%p) Unhandled query type %d\n",This , Type);
}
TRACE("(%p) : Created Query %p\n", This, object);
return WINED3D_OK;
}
/*****************************************************************************
* IWineD3DDeviceImpl_SetupFullscreenWindow
*
* Helper function that modifies a HWND's Style and ExStyle for proper
* fullscreen use.
*
* Params:
* iface: Pointer to the IWineD3DDevice interface
* window: Window to setup
*
*****************************************************************************/
static void WINAPI IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDevice *iface, HWND window) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
LONG style, exStyle;
/* Don't do anything if an original style is stored.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -