2004-10-07 06:22:21 +02:00
/*
* IWineD3DDevice implementation
*
2006-04-18 23:15:56 +02:00
* Copyright 2002 Lionel Ulmer
2005-03-02 13:16:10 +01:00
* Copyright 2002 - 2005 Jason Edmeades
2004-10-07 06:22:21 +02:00
* Copyright 2003 - 2004 Raphael Junqueira
* Copyright 2004 Christian Costa
2005-03-02 13:16:10 +01:00
* Copyright 2005 Oliver Stieber
2008-10-18 19:21:20 +02:00
* Copyright 2006 - 2008 Stefan Dösinger for CodeWeavers
2008-08-21 18:34:55 +02:00
* Copyright 2006 - 2008 Henri Verbeet
2007-05-15 00:37:53 +02:00
* Copyright 2007 Andrew Riedi
2009-09-10 16:57:16 +02:00
* Copyright 2009 Henri Verbeet for CodeWeavers
2004-10-07 06:22:21 +02:00
*
* 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
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2004-10-07 06:22:21 +02:00
*/
# include "config.h"
2006-06-09 09:36:55 +02:00
# include <stdio.h>
2006-02-13 13:23:42 +01:00
# ifdef HAVE_FLOAT_H
# include <float.h>
# endif
2004-10-07 06:22:21 +02:00
# include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL ( d3d ) ;
2007-06-09 14:27:41 +02:00
# define GLINFO_LOCATION This->adapter->gl_info
2004-10-07 06:22:21 +02:00
2006-06-07 05:37:05 +02:00
/* Define the default light parameters as specified by MSDN */
const WINED3DLIGHT WINED3D_default_light = {
2009-07-07 11:08:01 +02:00
WINED3DLIGHT_DIRECTIONAL , /* Type */
{ 1.0f , 1.0f , 1.0f , 0.0f } , /* Diffuse r,g,b,a */
{ 0.0f , 0.0f , 0.0f , 0.0f } , /* Specular r,g,b,a */
{ 0.0f , 0.0f , 0.0f , 0.0f } , /* Ambient r,g,b,a, */
{ 0.0f , 0.0f , 0.0f } , /* Position x,y,z */
{ 0.0f , 0.0f , 1.0f } , /* Direction x,y,z */
0.0f , /* Range */
0.0f , /* Falloff */
0.0f , 0.0f , 0.0f , /* Attenuation 0,1,2 */
0.0f , /* Theta */
0.0f /* Phi */
2006-06-07 05:37:05 +02:00
} ;
2004-10-07 06:22:21 +02:00
/**********************************************************
2004-11-28 16:04:41 +01:00
* Global variable / Constants follow
2004-10-07 06:22:21 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-07-07 11:08:01 +02:00
const float identity [ ] =
{
1.0f , 0.0f , 0.0f , 0.0f ,
0.0f , 1.0f , 0.0f , 0.0f ,
0.0f , 0.0f , 1.0f , 0.0f ,
0.0f , 0.0f , 0.0f , 1.0f ,
} ; /* When needed for comparisons */
2004-10-07 06:22:21 +02:00
2009-03-05 12:30:43 +01:00
/* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
* actually have the same values in GL and D3D . */
static GLenum gl_primitive_type_from_d3d ( WINED3DPRIMITIVETYPE primitive_type )
{
switch ( primitive_type )
{
case WINED3DPT_POINTLIST :
return GL_POINTS ;
case WINED3DPT_LINELIST :
return GL_LINES ;
case WINED3DPT_LINESTRIP :
return GL_LINE_STRIP ;
case WINED3DPT_TRIANGLELIST :
return GL_TRIANGLES ;
case WINED3DPT_TRIANGLESTRIP :
return GL_TRIANGLE_STRIP ;
case WINED3DPT_TRIANGLEFAN :
return GL_TRIANGLE_FAN ;
case WINED3DPT_LINELIST_ADJ :
return GL_LINES_ADJACENCY_ARB ;
case WINED3DPT_LINESTRIP_ADJ :
return GL_LINE_STRIP_ADJACENCY_ARB ;
case WINED3DPT_TRIANGLELIST_ADJ :
return GL_TRIANGLES_ADJACENCY_ARB ;
case WINED3DPT_TRIANGLESTRIP_ADJ :
return GL_TRIANGLE_STRIP_ADJACENCY_ARB ;
default :
FIXME ( " Unhandled primitive type %s \n " , debug_d3dprimitivetype ( primitive_type ) ) ;
return GL_NONE ;
}
}
static WINED3DPRIMITIVETYPE d3d_primitive_type_from_gl ( GLenum primitive_type )
{
switch ( primitive_type )
{
case GL_POINTS :
return WINED3DPT_POINTLIST ;
case GL_LINES :
return WINED3DPT_LINELIST ;
case GL_LINE_STRIP :
return WINED3DPT_LINESTRIP ;
case GL_TRIANGLES :
return WINED3DPT_TRIANGLELIST ;
case GL_TRIANGLE_STRIP :
return WINED3DPT_TRIANGLESTRIP ;
case GL_TRIANGLE_FAN :
return WINED3DPT_TRIANGLEFAN ;
case GL_LINES_ADJACENCY_ARB :
return WINED3DPT_LINELIST_ADJ ;
case GL_LINE_STRIP_ADJACENCY_ARB :
return WINED3DPT_LINESTRIP_ADJ ;
case GL_TRIANGLES_ADJACENCY_ARB :
return WINED3DPT_TRIANGLELIST_ADJ ;
case GL_TRIANGLE_STRIP_ADJACENCY_ARB :
return WINED3DPT_TRIANGLESTRIP_ADJ ;
default :
FIXME ( " Unhandled primitive type %s \n " , debug_d3dprimitivetype ( primitive_type ) ) ;
return WINED3DPT_UNDEFINED ;
}
}
2009-03-27 10:25:55 +01:00
static BOOL fixed_get_input ( BYTE usage , BYTE usage_idx , unsigned int * regnum )
{
if ( ( usage = = WINED3DDECLUSAGE_POSITION | | usage = = WINED3DDECLUSAGE_POSITIONT ) & & usage_idx = = 0 )
* regnum = WINED3D_FFP_POSITION ;
else if ( usage = = WINED3DDECLUSAGE_BLENDWEIGHT & & usage_idx = = 0 )
* regnum = WINED3D_FFP_BLENDWEIGHT ;
else if ( usage = = WINED3DDECLUSAGE_BLENDINDICES & & usage_idx = = 0 )
* regnum = WINED3D_FFP_BLENDINDICES ;
else if ( usage = = WINED3DDECLUSAGE_NORMAL & & usage_idx = = 0 )
* regnum = WINED3D_FFP_NORMAL ;
else if ( usage = = WINED3DDECLUSAGE_PSIZE & & usage_idx = = 0 )
* regnum = WINED3D_FFP_PSIZE ;
else if ( usage = = WINED3DDECLUSAGE_COLOR & & usage_idx = = 0 )
* regnum = WINED3D_FFP_DIFFUSE ;
else if ( usage = = WINED3DDECLUSAGE_COLOR & & usage_idx = = 1 )
* regnum = WINED3D_FFP_SPECULAR ;
else if ( usage = = WINED3DDECLUSAGE_TEXCOORD & & usage_idx < WINED3DDP_MAXTEXCOORD )
* regnum = WINED3D_FFP_TEXCOORD0 + usage_idx ;
else
{
FIXME ( " Unsupported input stream [usage=%s, usage_idx=%u] \n " , debug_d3ddeclusage ( usage ) , usage_idx ) ;
* regnum = ~ 0U ;
return FALSE ;
}
return TRUE ;
}
2009-06-26 10:07:12 +02:00
/* Context activation is done by the caller. */
2009-03-27 10:25:55 +01:00
void device_stream_info_from_declaration ( IWineD3DDeviceImpl * This ,
BOOL use_vshader , struct wined3d_stream_info * stream_info , BOOL * fixup )
{
/* We need to deal with frequency data! */
IWineD3DVertexDeclarationImpl * declaration = ( IWineD3DVertexDeclarationImpl * ) This - > stateBlock - > vertexDecl ;
unsigned int i ;
2009-08-27 10:04:53 +02:00
stream_info - > use_map = 0 ;
stream_info - > swizzle_map = 0 ;
2009-03-27 10:25:55 +01:00
/* Check for transformed vertices, disable vertex shader if present. */
stream_info - > position_transformed = declaration - > position_transformed ;
if ( declaration - > position_transformed ) use_vshader = FALSE ;
/* Translate the declaration into strided data. */
2009-03-27 10:25:56 +01:00
for ( i = 0 ; i < declaration - > element_count ; + + i )
2009-03-27 10:25:55 +01:00
{
2009-03-27 10:25:56 +01:00
const struct wined3d_vertex_declaration_element * element = & declaration - > elements [ i ] ;
2009-03-27 10:25:55 +01:00
GLuint buffer_object = 0 ;
const BYTE * data = NULL ;
BOOL stride_used ;
unsigned int idx ;
DWORD stride ;
2009-03-27 10:25:56 +01:00
TRACE ( " %p Element %p (%u of %u) \n " , declaration - > elements ,
element , i + 1 , declaration - > element_count ) ;
2009-03-27 10:25:55 +01:00
2009-03-27 10:25:56 +01:00
if ( ! This - > stateBlock - > streamSource [ element - > input_slot ] ) continue ;
2009-03-27 10:25:55 +01:00
2009-03-27 10:25:56 +01:00
stride = This - > stateBlock - > streamStride [ element - > input_slot ] ;
2009-03-27 10:25:55 +01:00
if ( This - > stateBlock - > streamIsUP )
{
2009-03-27 10:25:56 +01:00
TRACE ( " Stream %u is UP, %p \n " , element - > input_slot , This - > stateBlock - > streamSource [ element - > input_slot ] ) ;
2009-03-27 10:25:55 +01:00
buffer_object = 0 ;
2009-03-27 10:25:56 +01:00
data = ( BYTE * ) This - > stateBlock - > streamSource [ element - > input_slot ] ;
2009-03-27 10:25:55 +01:00
}
else
{
2009-03-27 10:25:56 +01:00
TRACE ( " Stream %u isn't UP, %p \n " , element - > input_slot , This - > stateBlock - > streamSource [ element - > input_slot ] ) ;
2010-04-09 15:47:23 +02:00
data = buffer_get_memory ( This - > stateBlock - > streamSource [ element - > input_slot ] , & buffer_object ) ;
2009-03-27 10:25:55 +01:00
/* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets
* ( or rather offsets bigger than the vbo , because the pointer is unsigned ) , so use system memory
* sources . In most sane cases the pointer - offset will still be > 0 , otherwise it will wrap
* around to some big value . Hope that with the indices , the driver wraps it back internally . If
* not , drawStridedSlow is needed , including a vertex buffer path . */
if ( This - > stateBlock - > loadBaseVertexIndex < 0 )
{
WARN ( " loadBaseVertexIndex is < 0 (%d), not using vbos \n " , This - > stateBlock - > loadBaseVertexIndex ) ;
buffer_object = 0 ;
2009-04-19 20:42:08 +02:00
data = buffer_get_sysmem ( ( struct wined3d_buffer * ) This - > stateBlock - > streamSource [ element - > input_slot ] ) ;
2009-03-27 10:25:55 +01:00
if ( ( UINT_PTR ) data < - This - > stateBlock - > loadBaseVertexIndex * stride )
{
FIXME ( " System memory vertex data load offset is negative! \n " ) ;
}
}
if ( fixup )
{
if ( buffer_object ) * fixup = TRUE ;
else if ( * fixup & & ! use_vshader
2009-03-27 10:25:56 +01:00
& & ( element - > usage = = WINED3DDECLUSAGE_COLOR
| | element - > usage = = WINED3DDECLUSAGE_POSITIONT ) )
2009-03-27 10:25:55 +01:00
{
static BOOL warned = FALSE ;
if ( ! warned )
{
/* This may be bad with the fixed function pipeline. */
FIXME ( " Missing vbo streams with unfixed colors or transformed position, expect problems \n " ) ;
warned = TRUE ;
}
}
}
}
2009-03-27 10:25:56 +01:00
data + = element - > offset ;
2009-03-27 10:25:55 +01:00
2009-03-27 10:25:56 +01:00
TRACE ( " offset %u input_slot %u usage_idx %d \n " , element - > offset , element - > input_slot , element - > usage_idx ) ;
2009-03-27 10:25:55 +01:00
if ( use_vshader )
{
2009-03-30 11:24:54 +02:00
if ( element - > output_slot = = ~ 0U )
{
/* TODO: Assuming vertexdeclarations are usually used with the
* same or a similar shader , it might be worth it to store the
* last used output slot and try that one first . */
stride_used = vshader_get_input ( This - > stateBlock - > vertexShader ,
element - > usage , element - > usage_idx , & idx ) ;
}
else
{
idx = element - > output_slot ;
stride_used = TRUE ;
}
2009-03-27 10:25:55 +01:00
}
else
{
2009-03-27 10:25:56 +01:00
if ( ! element - > ffp_valid )
2009-03-27 10:25:55 +01:00
{
2009-03-27 10:25:56 +01:00
WARN ( " Skipping unsupported fixed function element of format %s and usage %s \n " ,
debug_d3dformat ( element - > format_desc - > format ) , debug_d3ddeclusage ( element - > usage ) ) ;
2009-03-27 10:25:55 +01:00
stride_used = FALSE ;
}
else
{
2009-03-27 10:25:56 +01:00
stride_used = fixed_get_input ( element - > usage , element - > usage_idx , & idx ) ;
2009-03-27 10:25:55 +01:00
}
}
if ( stride_used )
{
TRACE ( " Load %s array %u [usage %s, usage_idx %u, "
2009-03-27 10:25:56 +01:00
" input_slot %u, offset %u, stride %u, format %s, buffer_object %u] \n " ,
2009-03-27 10:25:55 +01:00
use_vshader ? " shader " : " fixed function " , idx ,
2009-03-27 10:25:56 +01:00
debug_d3ddeclusage ( element - > usage ) , element - > usage_idx , element - > input_slot ,
element - > offset , stride , debug_d3dformat ( element - > format_desc - > format ) , buffer_object ) ;
2009-03-30 11:24:54 +02:00
stream_info - > elements [ idx ] . format_desc = element - > format_desc ;
2009-03-27 10:25:55 +01:00
stream_info - > elements [ idx ] . stride = stride ;
stream_info - > elements [ idx ] . data = data ;
2009-03-27 10:25:56 +01:00
stream_info - > elements [ idx ] . stream_idx = element - > input_slot ;
2009-03-27 10:25:55 +01:00
stream_info - > elements [ idx ] . buffer_object = buffer_object ;
2010-01-25 19:51:31 +01:00
if ( ! This - > adapter - > gl_info . supported [ ARB_VERTEX_ARRAY_BGRA ]
2009-10-29 10:37:11 +01:00
& & element - > format_desc - > format = = WINED3DFMT_B8G8R8A8_UNORM )
2009-03-27 10:25:55 +01:00
{
stream_info - > swizzle_map | = 1 < < idx ;
}
stream_info - > use_map | = 1 < < idx ;
}
}
2010-03-21 13:26:36 +01:00
This - > num_buffer_queries = 0 ;
2010-02-16 09:50:39 +01:00
if ( ! This - > stateBlock - > streamIsUP )
2009-03-27 10:25:55 +01:00
{
2010-02-16 09:50:39 +01:00
WORD map = stream_info - > use_map ;
/* PreLoad all the vertex buffers. */
for ( i = 0 ; map ; map > > = 1 , + + i )
{
struct wined3d_stream_info_element * element ;
struct wined3d_buffer * buffer ;
2010-03-21 13:26:36 +01:00
struct wined3d_event_query * query ;
2010-02-16 09:50:39 +01:00
if ( ! ( map & 1 ) ) continue ;
element = & stream_info - > elements [ i ] ;
buffer = ( struct wined3d_buffer * ) This - > stateBlock - > streamSource [ element - > stream_idx ] ;
IWineD3DBuffer_PreLoad ( ( IWineD3DBuffer * ) buffer ) ;
/* If PreLoad dropped the buffer object, update the stream info. */
if ( buffer - > buffer_object ! = element - > buffer_object )
{
element - > buffer_object = 0 ;
element - > data = buffer_get_sysmem ( buffer ) + ( ptrdiff_t ) element - > data ;
}
2010-03-21 13:26:36 +01:00
query = ( ( struct wined3d_buffer * ) buffer ) - > query ;
if ( query )
{
This - > buffer_queries [ This - > num_buffer_queries + + ] = query ;
}
2010-02-16 09:50:39 +01:00
}
2009-03-27 10:25:55 +01:00
}
}
2009-10-29 10:37:12 +01:00
static void stream_info_element_from_strided ( const struct wined3d_gl_info * gl_info ,
2009-03-27 10:25:55 +01:00
const struct WineDirect3DStridedData * strided , struct wined3d_stream_info_element * e )
{
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * format_desc = getFormatDescEntry ( strided - > format , gl_info ) ;
2009-03-30 11:24:54 +02:00
e - > format_desc = format_desc ;
2009-03-27 10:25:55 +01:00
e - > stride = strided - > dwStride ;
e - > data = strided - > lpData ;
e - > stream_idx = 0 ;
e - > buffer_object = 0 ;
}
2010-02-03 11:02:22 +01:00
static void device_stream_info_from_strided ( const struct wined3d_gl_info * gl_info ,
2009-03-27 10:25:55 +01:00
const struct WineDirect3DVertexStridedData * strided , struct wined3d_stream_info * stream_info )
{
unsigned int i ;
memset ( stream_info , 0 , sizeof ( * stream_info ) ) ;
if ( strided - > position . lpData )
2009-10-29 10:37:12 +01:00
stream_info_element_from_strided ( gl_info , & strided - > position , & stream_info - > elements [ WINED3D_FFP_POSITION ] ) ;
2009-03-27 10:25:55 +01:00
if ( strided - > normal . lpData )
2009-10-29 10:37:12 +01:00
stream_info_element_from_strided ( gl_info , & strided - > normal , & stream_info - > elements [ WINED3D_FFP_NORMAL ] ) ;
2009-03-27 10:25:55 +01:00
if ( strided - > diffuse . lpData )
2009-10-29 10:37:12 +01:00
stream_info_element_from_strided ( gl_info , & strided - > diffuse , & stream_info - > elements [ WINED3D_FFP_DIFFUSE ] ) ;
2009-03-27 10:25:55 +01:00
if ( strided - > specular . lpData )
2009-10-29 10:37:12 +01:00
stream_info_element_from_strided ( gl_info , & strided - > specular , & stream_info - > elements [ WINED3D_FFP_SPECULAR ] ) ;
2009-03-27 10:25:55 +01:00
for ( i = 0 ; i < WINED3DDP_MAXTEXCOORD ; + + i )
{
if ( strided - > texCoords [ i ] . lpData )
2009-10-29 10:37:12 +01:00
stream_info_element_from_strided ( gl_info , & strided - > texCoords [ i ] ,
2009-03-27 10:25:55 +01:00
& stream_info - > elements [ WINED3D_FFP_TEXCOORD0 + i ] ) ;
}
stream_info - > position_transformed = strided - > position_transformed ;
for ( i = 0 ; i < sizeof ( stream_info - > elements ) / sizeof ( * stream_info - > elements ) ; + + i )
{
2009-04-09 09:58:27 +02:00
if ( ! stream_info - > elements [ i ] . format_desc ) continue ;
2010-01-25 19:51:31 +01:00
if ( ! gl_info - > supported [ ARB_VERTEX_ARRAY_BGRA ]
2009-09-25 13:31:49 +02:00
& & stream_info - > elements [ i ] . format_desc - > format = = WINED3DFMT_B8G8R8A8_UNORM )
2009-03-27 10:25:55 +01:00
{
stream_info - > swizzle_map | = 1 < < i ;
}
stream_info - > use_map | = 1 < < i ;
}
}
2009-03-05 12:30:43 +01:00
2010-02-03 11:02:22 +01:00
static void device_trace_strided_stream_info ( const struct wined3d_stream_info * stream_info )
{
TRACE ( " Strided Data: \n " ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_POSITION ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_BLENDWEIGHT ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_BLENDINDICES ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_NORMAL ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_PSIZE ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_DIFFUSE ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_SPECULAR ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD0 ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD1 ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD2 ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD3 ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD4 ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD5 ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD6 ) ;
TRACE_STRIDED ( stream_info , WINED3D_FFP_TEXCOORD7 ) ;
}
/* Context activation is done by the caller. */
void device_update_stream_info ( IWineD3DDeviceImpl * device , const struct wined3d_gl_info * gl_info )
{
struct wined3d_stream_info * stream_info = & device - > strided_streams ;
IWineD3DStateBlockImpl * stateblock = device - > stateBlock ;
BOOL vs = stateblock - > vertexShader & & device - > vs_selected_mode ! = SHADER_NONE ;
BOOL fixup = FALSE ;
if ( device - > up_strided )
{
/* Note: this is a ddraw fixed-function code path. */
TRACE ( " =============================== Strided Input ================================ \n " ) ;
device_stream_info_from_strided ( gl_info , device - > up_strided , stream_info ) ;
if ( TRACE_ON ( d3d ) ) device_trace_strided_stream_info ( stream_info ) ;
}
else
{
TRACE ( " ============================= Vertex Declaration ============================= \n " ) ;
device_stream_info_from_declaration ( device , vs , stream_info , & fixup ) ;
}
if ( vs & & ! stream_info - > position_transformed )
{
if ( ( ( IWineD3DVertexDeclarationImpl * ) stateblock - > vertexDecl ) - > half_float_conv_needed & & ! fixup )
{
TRACE ( " Using drawStridedSlow with vertex shaders for FLOAT16 conversion. \n " ) ;
device - > useDrawStridedSlow = TRUE ;
}
else
{
device - > useDrawStridedSlow = FALSE ;
}
}
else
{
WORD slow_mask = ( 1 < < WINED3D_FFP_PSIZE ) ;
slow_mask | = - ! gl_info - > supported [ ARB_VERTEX_ARRAY_BGRA ]
& ( ( 1 < < WINED3D_FFP_DIFFUSE ) | ( 1 < < WINED3D_FFP_SPECULAR ) ) ;
if ( ( stream_info - > position_transformed | | ( stream_info - > use_map & slow_mask ) ) & & ! fixup )
{
device - > useDrawStridedSlow = TRUE ;
}
else
{
device - > useDrawStridedSlow = FALSE ;
}
}
}
2010-02-03 11:02:21 +01:00
static void device_preload_texture ( IWineD3DStateBlockImpl * stateblock , unsigned int idx )
{
IWineD3DBaseTextureImpl * texture ;
enum WINED3DSRGB srgb ;
if ( ! ( texture = ( IWineD3DBaseTextureImpl * ) stateblock - > textures [ idx ] ) ) return ;
srgb = stateblock - > samplerState [ idx ] [ WINED3DSAMP_SRGBTEXTURE ] ? SRGB_SRGB : SRGB_RGB ;
texture - > baseTexture . internal_preload ( ( IWineD3DBaseTexture * ) texture , srgb ) ;
}
void device_preload_textures ( IWineD3DDeviceImpl * device )
{
IWineD3DStateBlockImpl * stateblock = device - > stateBlock ;
unsigned int i ;
if ( use_vs ( stateblock ) )
{
for ( i = 0 ; i < MAX_VERTEX_SAMPLERS ; + + i )
{
if ( ( ( IWineD3DBaseShaderImpl * ) stateblock - > vertexShader ) - > baseShader . reg_maps . sampler_type [ i ] )
device_preload_texture ( stateblock , MAX_FRAGMENT_SAMPLERS + i ) ;
}
}
if ( use_ps ( stateblock ) )
{
for ( i = 0 ; i < MAX_FRAGMENT_SAMPLERS ; + + i )
{
if ( ( ( IWineD3DBaseShaderImpl * ) stateblock - > pixelShader ) - > baseShader . reg_maps . sampler_type [ i ] )
device_preload_texture ( stateblock , i ) ;
}
}
else
{
WORD ffu_map = device - > fixed_function_usage_map ;
for ( i = 0 ; ffu_map ; ffu_map > > = 1 , + + i )
{
if ( ffu_map & 1 )
device_preload_texture ( stateblock , i ) ;
}
}
}
2010-03-14 21:53:25 +01:00
BOOL device_context_add ( IWineD3DDeviceImpl * device , struct wined3d_context * context )
{
struct wined3d_context * * new_array ;
TRACE ( " Adding context %p. \n " , context ) ;
if ( ! device - > contexts ) new_array = HeapAlloc ( GetProcessHeap ( ) , 0 , sizeof ( * new_array ) ) ;
else new_array = HeapReAlloc ( GetProcessHeap ( ) , 0 , device - > contexts , sizeof ( * new_array ) * ( device - > numContexts + 1 ) ) ;
if ( ! new_array )
{
ERR ( " Failed to grow the context array. \n " ) ;
return FALSE ;
}
new_array [ device - > numContexts + + ] = context ;
device - > contexts = new_array ;
return TRUE ;
}
void device_context_remove ( IWineD3DDeviceImpl * device , struct wined3d_context * context )
{
struct wined3d_context * * new_array ;
BOOL found = FALSE ;
UINT i ;
TRACE ( " Removing context %p. \n " , context ) ;
for ( i = 0 ; i < device - > numContexts ; + + i )
{
if ( device - > contexts [ i ] = = context )
{
found = TRUE ;
break ;
}
}
if ( ! found )
{
ERR ( " Context %p doesn't exist in context array. \n " , context ) ;
return ;
}
if ( ! - - device - > numContexts )
{
HeapFree ( GetProcessHeap ( ) , 0 , device - > contexts ) ;
device - > contexts = NULL ;
return ;
}
memmove ( & device - > contexts [ i ] , & device - > contexts [ i + 1 ] , ( device - > numContexts - i ) * sizeof ( * device - > contexts ) ) ;
new_array = HeapReAlloc ( GetProcessHeap ( ) , 0 , device - > contexts , device - > numContexts * sizeof ( * device - > contexts ) ) ;
if ( ! new_array )
{
ERR ( " Failed to shrink context array. Oh well. \n " ) ;
return ;
}
device - > contexts = new_array ;
}
2010-04-28 00:08:50 +02:00
static void device_get_draw_rect ( IWineD3DDeviceImpl * device , RECT * rect )
{
IWineD3DStateBlockImpl * stateblock = device - > stateBlock ;
WINED3DVIEWPORT * vp = & stateblock - > viewport ;
SetRect ( rect , vp - > X , vp - > Y , vp - > X + vp - > Width , vp - > Y + vp - > Height ) ;
if ( stateblock - > renderState [ WINED3DRS_SCISSORTESTENABLE ] )
{
IntersectRect ( rect , rect , & stateblock - > scissorRect ) ;
}
}
2010-04-20 22:38:41 +02:00
void device_switch_onscreen_ds ( IWineD3DDeviceImpl * device ,
struct wined3d_context * context , IWineD3DSurfaceImpl * depth_stencil )
{
if ( device - > onscreen_depth_stencil )
{
surface_load_ds_location ( device - > onscreen_depth_stencil , context , SFLAG_DS_OFFSCREEN ) ;
surface_modify_ds_location ( device - > onscreen_depth_stencil , SFLAG_DS_OFFSCREEN ) ;
IWineD3DSurface_Release ( ( IWineD3DSurface * ) device - > onscreen_depth_stencil ) ;
}
device - > onscreen_depth_stencil = depth_stencil ;
IWineD3DSurface_AddRef ( ( IWineD3DSurface * ) device - > onscreen_depth_stencil ) ;
}
2010-03-14 21:53:25 +01:00
2005-03-02 13:16:10 +01:00
/**********************************************************
* IUnknown parts follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_QueryInterface ( IWineD3DDevice * iface , REFIID riid , LPVOID * ppobj )
2005-03-02 13:16:10 +01:00
{
2005-03-02 14:44:58 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
2005-03-02 14:44:58 +01:00
TRACE ( " (%p)->(%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
2005-07-13 16:15:54 +02:00
if ( IsEqualGUID ( riid , & IID_IUnknown )
2006-02-06 11:32:41 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DBase )
2005-03-02 14:44:58 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DDevice ) ) {
IUnknown_AddRef ( iface ) ;
* ppobj = This ;
2006-04-25 23:59:12 +02:00
return S_OK ;
2005-03-02 14:44:58 +01:00
}
2006-04-25 23:59:12 +02:00
* ppobj = NULL ;
2005-03-02 13:16:10 +01:00
return E_NOINTERFACE ;
}
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DDeviceImpl_AddRef ( IWineD3DDevice * iface ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
ULONG refCount = InterlockedIncrement ( & This - > ref ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : AddRef increasing from %d \n " , This , refCount - 1 ) ;
2005-03-02 13:16:10 +01:00
return refCount ;
}
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DDeviceImpl_Release ( IWineD3DDevice * iface ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
ULONG refCount = InterlockedDecrement ( & This - > ref ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Releasing from %d \n " , This , refCount + 1 ) ;
2005-03-02 13:16:10 +01:00
if ( ! refCount ) {
2009-01-07 02:20:08 +01:00
UINT i ;
for ( i = 0 ; i < sizeof ( This - > multistate_funcs ) / sizeof ( This - > multistate_funcs [ 0 ] ) ; + + i ) {
HeapFree ( GetProcessHeap ( ) , 0 , This - > multistate_funcs [ i ] ) ;
This - > multistate_funcs [ i ] = NULL ;
}
2005-03-02 13:16:10 +01:00
/* TODO: Clean up all the surfaces and textures! */
2006-04-18 22:38:30 +02:00
/* NOTE: You must release the parent if the object was created via a callback
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-23 12:07:46 +02:00
2010-04-04 19:51:38 +02:00
if ( ! list_empty ( & This - > resources ) )
{
IWineD3DResourceImpl * resource ;
2006-04-18 22:38:30 +02:00
FIXME ( " (%p) Device released with resources still bound, acceptable but unexpected \n " , This ) ;
2010-04-04 19:51:38 +02:00
LIST_FOR_EACH_ENTRY ( resource , & This - > resources , IWineD3DResourceImpl , resource . resource_list_entry )
{
WINED3DRESOURCETYPE type = IWineD3DResource_GetType ( ( IWineD3DResource * ) resource ) ;
FIXME ( " Leftover resource %p with type %s (%#x). \n " ,
resource , debug_d3dresourcetype ( type ) , type ) ;
}
2006-04-18 22:38:30 +02:00
}
2005-06-23 13:05:24 +02:00
2007-02-12 19:21:10 +01:00
if ( This - > contexts ) ERR ( " Context array not freed! \n " ) ;
2007-05-15 00:37:53 +02:00
if ( This - > hardwareCursor ) DestroyCursor ( This - > hardwareCursor ) ;
This - > haveHardwareCursor = FALSE ;
2005-09-23 12:07:46 +02:00
2009-12-07 20:20:02 +01:00
IWineD3D_Release ( This - > wined3d ) ;
This - > wined3d = NULL ;
2005-03-02 13:16:10 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
2005-11-10 13:14:56 +01:00
TRACE ( " Freed device %p \n " , This ) ;
2005-09-23 12:07:46 +02:00
This = NULL ;
2005-03-02 13:16:10 +01:00
}
return refCount ;
2004-12-13 14:35:38 +01:00
}
2004-10-07 06:22:21 +02:00
/**********************************************************
* IWineD3DDevice implementation follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetParent ( IWineD3DDevice * iface , IUnknown * * pParent ) {
2004-11-23 14:52:46 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
* pParent = This - > parent ;
IUnknown_AddRef ( This - > parent ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-23 14:52:46 +01:00
}
2009-09-17 23:03:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer ( IWineD3DDevice * iface , struct wined3d_buffer_desc * desc ,
const void * data , IUnknown * parent , const struct wined3d_parent_ops * parent_ops , IWineD3DBuffer * * buffer )
2009-02-23 09:16:02 +01:00
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
struct wined3d_buffer * object ;
HRESULT hr ;
2009-03-31 09:38:14 +02:00
TRACE ( " iface %p, desc %p, data %p, parent %p, buffer %p \n " , iface , desc , data , parent , buffer ) ;
2009-02-23 09:16:02 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Failed to allocate memory \n " ) ;
return E_OUTOFMEMORY ;
}
FIXME ( " Ignoring access flags (pool) \n " ) ;
2009-09-17 23:03:32 +02:00
hr = buffer_init ( object , This , desc - > byte_width , desc - > usage , WINED3DFMT_UNKNOWN ,
WINED3DPOOL_MANAGED , GL_ARRAY_BUFFER_ARB , data , parent , parent_ops ) ;
2009-02-23 09:16:02 +01:00
if ( FAILED ( hr ) )
{
2009-09-17 23:03:26 +02:00
WARN ( " Failed to initialize buffer, hr %#x. \n " , hr ) ;
2009-02-23 09:16:02 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
}
2009-09-17 23:03:26 +02:00
object - > desc = * desc ;
2009-03-31 09:38:14 +02:00
2009-09-17 23:03:26 +02:00
TRACE ( " Created buffer %p. \n " , object ) ;
2009-03-31 09:38:14 +02:00
2009-02-23 09:16:02 +01:00
* buffer = ( IWineD3DBuffer * ) object ;
return WINED3D_OK ;
}
2009-12-29 17:10:19 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer ( IWineD3DDevice * iface ,
UINT Size , DWORD Usage , WINED3DPOOL Pool , IWineD3DBuffer * * ppVertexBuffer ,
2009-09-17 23:03:32 +02:00
IUnknown * parent , const struct wined3d_parent_ops * parent_ops )
2009-03-06 14:56:23 +01:00
{
2004-10-14 02:32:04 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-06 14:56:23 +01:00
struct wined3d_buffer * object ;
2009-01-13 10:31:57 +01:00
HRESULT hr ;
2007-02-13 20:24:39 +01:00
2009-12-29 17:10:19 +01:00
TRACE ( " iface %p, size %u, usage %#x, pool %#x, buffer %p, parent %p, parent_ops %p. \n " ,
iface , Size , Usage , Pool , ppVertexBuffer , parent , parent_ops ) ;
2009-09-17 23:03:26 +02:00
if ( Pool = = WINED3DPOOL_SCRATCH )
{
2007-10-22 13:30:14 +02:00
/* The d3d9 testsuit shows that this is not allowed. It doesn't make much sense
2008-05-06 15:54:52 +02:00
* anyway , SCRATCH vertex buffers aren ' t usable anywhere
2007-10-22 13:30:14 +02:00
*/
WARN ( " Vertex buffer in D3DPOOL_SCRATCH requested, returning WINED3DERR_INVALIDCALL \n " ) ;
2007-02-13 20:24:39 +01:00
* ppVertexBuffer = NULL ;
return WINED3DERR_INVALIDCALL ;
}
2009-01-13 10:31:57 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Out of memory \n " ) ;
* ppVertexBuffer = NULL ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
2009-09-17 23:03:32 +02:00
hr = buffer_init ( object , This , Size , Usage , WINED3DFMT_VERTEXDATA ,
Pool , GL_ARRAY_BUFFER_ARB , NULL , parent , parent_ops ) ;
2009-01-13 10:31:57 +01:00
if ( FAILED ( hr ) )
{
2009-09-17 23:03:26 +02:00
WARN ( " Failed to initialize buffer, hr %#x. \n " , hr ) ;
2009-01-13 10:31:57 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
}
2009-09-17 23:03:26 +02:00
TRACE ( " Created buffer %p. \n " , object ) ;
2009-03-06 14:56:23 +01:00
* ppVertexBuffer = ( IWineD3DBuffer * ) object ;
2006-06-21 15:05:38 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-14 02:32:04 +02:00
}
2004-10-07 06:22:21 +02:00
2009-04-23 09:24:27 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer ( IWineD3DDevice * iface ,
2009-09-17 23:03:32 +02:00
UINT Length , DWORD Usage , WINED3DPOOL Pool , IWineD3DBuffer * * ppIndexBuffer ,
IUnknown * parent , const struct wined3d_parent_ops * parent_ops )
2009-04-23 09:24:27 +02:00
{
2004-11-24 19:13:41 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-04-06 13:38:56 +02:00
struct wined3d_buffer * object ;
2009-01-13 10:31:57 +01:00
HRESULT hr ;
2005-03-02 13:16:10 +01:00
TRACE ( " (%p) Creating index buffer \n " , This ) ;
2007-02-19 15:25:32 +01:00
2004-11-24 19:13:41 +01:00
/* Allocate the storage for the device */
2009-01-13 10:31:57 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Out of memory \n " ) ;
* ppIndexBuffer = NULL ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
2009-10-20 14:14:45 +02:00
hr = buffer_init ( object , This , Length , Usage | WINED3DUSAGE_STATICDECL ,
2009-12-28 00:31:12 +01:00
WINED3DFMT_UNKNOWN , Pool , GL_ELEMENT_ARRAY_BUFFER_ARB , NULL ,
parent , parent_ops ) ;
2009-01-13 10:31:57 +01:00
if ( FAILED ( hr ) )
{
2009-09-17 23:03:26 +02:00
WARN ( " Failed to initialize buffer, hr %#x \n " , hr ) ;
2009-01-13 10:31:57 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
}
2009-09-17 23:03:26 +02:00
TRACE ( " Created buffer %p. \n " , object ) ;
2009-01-13 10:31:57 +01:00
2009-04-06 16:46:12 +02:00
* ppIndexBuffer = ( IWineD3DBuffer * ) object ;
2004-11-24 19:13:41 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-24 19:13:41 +01:00
}
2009-09-29 11:09:04 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock ( IWineD3DDevice * iface ,
WINED3DSTATEBLOCKTYPE type , IWineD3DStateBlock * * stateblock , IUnknown * parent )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2004-10-21 22:59:12 +02:00
IWineD3DStateBlockImpl * object ;
2009-09-29 11:09:04 +02:00
HRESULT hr ;
2005-03-02 13:16:10 +01:00
2009-01-14 10:01:11 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
2009-09-29 11:09:04 +02:00
ERR ( " Failed to allocate stateblock memory. \n " ) ;
return E_OUTOFMEMORY ;
2007-02-14 17:46:54 +01:00
}
2009-12-04 11:50:48 +01:00
hr = stateblock_init ( object , This , type ) ;
2009-09-29 11:09:04 +02:00
if ( FAILED ( hr ) )
2008-12-18 17:59:06 +01:00
{
2009-09-29 11:09:04 +02:00
WARN ( " Failed to initialize stateblock, hr %#x. \n " , hr ) ;
2008-12-18 17:59:06 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
2009-09-29 11:09:04 +02:00
return hr ;
2004-10-21 22:59:12 +02:00
}
2009-09-29 11:09:04 +02:00
TRACE ( " Created stateblock %p. \n " , object ) ;
* stateblock = ( IWineD3DStateBlock * ) object ;
2005-07-05 16:05:18 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-21 22:59:12 +02:00
}
2009-06-12 09:46:03 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface ( IWineD3DDevice * iface , UINT Width , UINT Height ,
WINED3DFORMAT Format , BOOL Lockable , BOOL Discard , UINT Level , IWineD3DSurface * * ppSurface ,
DWORD Usage , WINED3DPOOL Pool , WINED3DMULTISAMPLE_TYPE MultiSample , DWORD MultisampleQuality ,
2009-09-16 08:37:15 +02:00
WINED3DSURFTYPE Impl , IUnknown * parent , const struct wined3d_parent_ops * parent_ops )
2009-04-23 09:24:27 +02:00
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-06-15 09:06:49 +02:00
IWineD3DSurfaceImpl * object ;
2009-01-13 10:31:57 +01:00
HRESULT hr ;
2010-02-02 12:06:54 +01:00
TRACE ( " iface %p, width %u, height %u, format %s (%#x), lockable %#x, discard %#x, level %u \n " ,
iface , Width , Height , debug_d3dformat ( Format ) , Format , Lockable , Discard , Level ) ;
TRACE ( " surface %p, usage %s (%#x), pool %s (%#x), multisample_type %#x, multisample_quality %u \n " ,
ppSurface , debug_d3dusage ( Usage ) , Usage , debug_d3dpool ( Pool ) , Pool , MultiSample , MultisampleQuality ) ;
TRACE ( " surface_type %#x, parent %p, parent_ops %p. \n " , Impl , parent , parent_ops ) ;
2005-07-13 16:15:54 +02:00
2009-06-15 09:06:49 +02:00
if ( Impl = = SURFACE_OPENGL & & ! This - > adapter )
2009-06-11 10:24:30 +02:00
{
2009-06-15 09:06:49 +02:00
ERR ( " OpenGL surfaces are not available without OpenGL. \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2009-06-11 10:24:30 +02:00
}
2008-08-26 21:36:30 +02:00
2009-01-13 10:31:57 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
2009-06-15 09:06:49 +02:00
ERR ( " Failed to allocate surface memory. \n " ) ;
2009-01-13 10:31:57 +01:00
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
2009-06-15 09:06:49 +02:00
hr = surface_init ( object , Impl , This - > surface_alignment , Width , Height , Level , Lockable ,
2009-09-16 08:37:15 +02:00
Discard , MultiSample , MultisampleQuality , This , Usage , Format , Pool , parent , parent_ops ) ;
2009-01-13 10:31:57 +01:00
if ( FAILED ( hr ) )
{
2009-06-15 09:06:49 +02:00
WARN ( " Failed to initialize surface, returning %#x. \n " , hr ) ;
2009-01-13 10:31:57 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
}
2009-06-15 09:06:49 +02:00
TRACE ( " (%p) : Created surface %p \n " , This , object ) ;
2009-01-13 10:31:57 +01:00
* ppSurface = ( IWineD3DSurface * ) object ;
2009-01-13 10:31:57 +01:00
return hr ;
2005-03-02 13:16:10 +01:00
}
2009-02-24 07:43:02 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView ( IWineD3DDevice * iface ,
IWineD3DResource * resource , IUnknown * parent , IWineD3DRendertargetView * * rendertarget_view )
{
struct wined3d_rendertarget_view * object ;
2010-04-13 20:46:24 +02:00
TRACE ( " iface %p, resource %p, parent %p, rendertarget_view %p. \n " ,
iface , resource , parent , rendertarget_view ) ;
2009-02-24 07:43:02 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Failed to allocate memory \n " ) ;
return E_OUTOFMEMORY ;
}
2010-04-13 20:46:24 +02:00
wined3d_rendertarget_view_init ( object , resource , parent ) ;
2009-02-24 07:43:02 +01:00
2010-04-13 20:46:24 +02:00
TRACE ( " Created render target view %p. \n " , object ) ;
2009-02-24 07:43:02 +01:00
* rendertarget_view = ( IWineD3DRendertargetView * ) object ;
return WINED3D_OK ;
}
2009-01-16 10:14:24 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture ( IWineD3DDevice * iface ,
2009-09-17 23:03:25 +02:00
UINT Width , UINT Height , UINT Levels , DWORD Usage , WINED3DFORMAT Format , WINED3DPOOL Pool ,
IWineD3DTexture * * ppTexture , IUnknown * parent , const struct wined3d_parent_ops * parent_ops )
2009-01-16 10:14:24 +01:00
{
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
IWineD3DTextureImpl * object ;
2005-03-02 13:16:10 +01:00
HRESULT hr ;
2005-08-03 21:49:05 +02:00
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Width %d, Height %d, Levels %d, Usage %#x \n " , This , Width , Height , Levels , Usage ) ;
2009-04-23 09:24:27 +02:00
TRACE ( " Format %#x (%s), Pool %#x, ppTexture %p, parent %p \n " ,
Format , debug_d3dformat ( Format ) , Pool , ppTexture , parent ) ;
2005-01-17 14:44:57 +01:00
2009-01-13 10:31:57 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Out of memory \n " ) ;
* ppTexture = NULL ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
2009-09-17 23:03:25 +02:00
hr = texture_init ( object , Width , Height , Levels , This , Usage , Format , Pool , parent , parent_ops ) ;
2009-01-13 10:31:57 +01:00
if ( FAILED ( hr ) )
{
2009-06-03 10:47:25 +02:00
WARN ( " Failed to initialize texture, returning %#x \n " , hr ) ;
2009-01-13 10:31:57 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
* ppTexture = NULL ;
return hr ;
}
* ppTexture = ( IWineD3DTexture * ) object ;
2009-06-03 10:47:25 +02:00
TRACE ( " (%p) : Created texture %p \n " , This , object ) ;
2005-07-13 16:15:54 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-17 14:44:57 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture ( IWineD3DDevice * iface ,
2009-09-16 08:37:24 +02:00
UINT Width , UINT Height , UINT Depth , UINT Levels , DWORD Usage , WINED3DFORMAT Format , WINED3DPOOL Pool ,
IWineD3DVolumeTexture * * ppVolumeTexture , IUnknown * parent , const struct wined3d_parent_ops * parent_ops )
2009-01-16 10:14:24 +01:00
{
2005-01-17 14:44:57 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DVolumeTextureImpl * object ;
2009-01-13 10:31:57 +01:00
HRESULT hr ;
2007-10-26 13:44:16 +02:00
2009-06-03 10:47:26 +02:00
TRACE ( " (%p) : W(%u) H(%u) D(%u), Lvl(%u) Usage(%#x), Fmt(%u,%s), Pool(%s) \n " , This , Width , Height ,
Depth , Levels , Usage , Format , debug_d3dformat ( Format ) , debug_d3dpool ( Pool ) ) ;
2009-01-13 10:31:57 +01:00
2009-01-13 10:31:57 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Out of memory \n " ) ;
* ppVolumeTexture = NULL ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
2009-09-16 08:37:24 +02:00
hr = volumetexture_init ( object , Width , Height , Depth , Levels , This , Usage , Format , Pool , parent , parent_ops ) ;
2009-01-13 10:31:57 +01:00
if ( FAILED ( hr ) )
{
2009-06-03 10:47:26 +02:00
WARN ( " Failed to initialize volumetexture, returning %#x \n " , hr ) ;
2009-01-13 10:31:57 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
* ppVolumeTexture = NULL ;
return hr ;
}
2009-06-03 10:47:26 +02:00
TRACE ( " (%p) : Created volume texture %p. \n " , This , object ) ;
* ppVolumeTexture = ( IWineD3DVolumeTexture * ) object ;
2005-01-17 14:44:57 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-17 14:44:57 +01:00
}
2009-09-16 08:37:19 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume ( IWineD3DDevice * iface , UINT Width , UINT Height ,
UINT Depth , DWORD Usage , WINED3DFORMAT Format , WINED3DPOOL Pool , IWineD3DVolume * * ppVolume ,
IUnknown * parent , const struct wined3d_parent_ops * parent_ops )
2009-04-23 09:24:27 +02:00
{
2009-09-16 08:37:16 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DVolumeImpl * object ;
2009-01-13 10:31:57 +01:00
HRESULT hr ;
2005-01-17 14:44:57 +01:00
2009-09-16 08:37:16 +02:00
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 ) ) ;
2007-10-26 13:44:16 +02:00
2009-01-13 10:31:57 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Out of memory \n " ) ;
* ppVolume = NULL ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
2009-09-16 08:37:19 +02:00
hr = volume_init ( object , This , Width , Height , Depth , Usage , Format , Pool , parent , parent_ops ) ;
2009-01-13 10:31:57 +01:00
if ( FAILED ( hr ) )
{
2009-09-16 08:37:16 +02:00
WARN ( " Failed to initialize volume, returning %#x. \n " , hr ) ;
2009-01-13 10:31:57 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
}
2009-09-16 08:37:16 +02:00
TRACE ( " (%p) : Created volume %p. \n " , This , object ) ;
2009-01-13 10:31:57 +01:00
* ppVolume = ( IWineD3DVolume * ) object ;
2005-01-17 14:44:57 +01:00
2009-01-14 10:01:10 +01:00
return WINED3D_OK ;
2005-01-17 14:44:57 +01:00
}
2009-09-17 12:35:25 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture ( IWineD3DDevice * iface , UINT EdgeLength , UINT Levels ,
DWORD Usage , WINED3DFORMAT Format , WINED3DPOOL Pool , IWineD3DCubeTexture * * ppCubeTexture ,
IUnknown * parent , const struct wined3d_parent_ops * parent_ops )
2009-01-16 10:14:24 +01:00
{
2005-08-03 21:49:05 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DCubeTextureImpl * object ; /** NOTE: impl ref allowed since this is a create function **/
HRESULT hr ;
2009-01-13 10:31:58 +01:00
2009-01-13 10:31:57 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Out of memory \n " ) ;
* ppCubeTexture = NULL ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
2009-09-17 12:35:25 +02:00
hr = cubetexture_init ( object , EdgeLength , Levels , This , Usage , Format , Pool , parent , parent_ops ) ;
2009-01-13 10:31:57 +01:00
if ( FAILED ( hr ) )
{
2009-06-03 10:47:26 +02:00
WARN ( " Failed to initialize cubetexture, returning %#x \n " , hr ) ;
2009-01-13 10:31:57 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
* ppCubeTexture = NULL ;
return hr ;
}
2005-01-17 14:44:57 +01:00
TRACE ( " (%p) : Created Cube Texture %p \n " , This , object ) ;
2009-06-03 10:47:26 +02:00
* ppCubeTexture = ( IWineD3DCubeTexture * ) object ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-17 14:44:57 +01:00
}
2010-01-17 21:31:30 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery ( IWineD3DDevice * iface ,
WINED3DQUERYTYPE type , IWineD3DQuery * * query , IUnknown * parent )
{
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2010-01-17 21:31:30 +01:00
IWineD3DQueryImpl * object ;
HRESULT hr ;
2008-02-28 21:03:41 +01:00
2010-01-17 21:31:30 +01:00
TRACE ( " iface %p, type %#x, query %p, parent %p. \n " , iface , type , query , parent ) ;
2007-02-16 19:14:46 +01:00
2010-01-17 21:31:30 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Failed to allocate query memory. \n " ) ;
return E_OUTOFMEMORY ;
2005-03-02 13:16:10 +01:00
}
2010-01-17 21:31:30 +01:00
hr = query_init ( object , This , type , parent ) ;
if ( FAILED ( hr ) )
2009-01-14 10:01:11 +01:00
{
2010-01-17 21:31:30 +01:00
WARN ( " Failed to initialize query, hr %#x. \n " , hr ) ;
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
2009-01-14 10:01:11 +01:00
}
2010-01-17 21:31:30 +01:00
TRACE ( " Created query %p. \n " , object ) ;
* query = ( IWineD3DQuery * ) object ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2009-01-16 10:14:24 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain ( IWineD3DDevice * iface ,
2009-12-10 21:41:54 +01:00
WINED3DPRESENT_PARAMETERS * present_parameters , IWineD3DSwapChain * * swapchain ,
2009-01-16 10:14:24 +01:00
IUnknown * parent , WINED3DSURFTYPE surface_type )
2008-10-28 09:27:20 +01:00
{
2009-12-10 21:41:54 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DSwapChainImpl * object ;
HRESULT hr ;
2005-06-23 13:05:24 +02:00
2009-12-10 21:41:54 +01:00
TRACE ( " iface %p, present_parameters %p, swapchain %p, parent %p, surface_type %#x. \n " ,
iface , present_parameters , swapchain , parent , surface_type ) ;
2006-05-24 11:34:30 +02:00
2009-01-14 10:01:11 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
2009-12-10 21:41:54 +01:00
if ( ! object )
2009-12-06 18:08:39 +01:00
{
2009-12-10 21:41:54 +01:00
ERR ( " Failed to allocate swapchain memory. \n " ) ;
return E_OUTOFMEMORY ;
2008-10-15 13:35:31 +02:00
}
2007-10-26 02:16:03 +02:00
2009-12-10 21:41:54 +01:00
hr = swapchain_init ( object , surface_type , This , present_parameters , parent ) ;
if ( FAILED ( hr ) )
2009-11-04 10:37:17 +01:00
{
2009-12-10 21:41:54 +01:00
WARN ( " Failed to initialize swapchain, hr %#x. \n " , hr ) ;
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
2005-06-23 13:05:24 +02:00
}
2009-12-10 21:41:54 +01:00
TRACE ( " Created swapchain %p. \n " , object ) ;
* swapchain = ( IWineD3DSwapChain * ) object ;
2008-07-01 18:17:38 +02:00
2007-02-12 19:22:41 +01:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-07-11 12:59:41 +02:00
/** NOTE: These are ahead of the other getters and setters to save using a forward declaration **/
2006-06-10 13:15:32 +02:00
static UINT WINAPI IWineD3DDeviceImpl_GetNumberOfSwapChains ( IWineD3DDevice * iface ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-05-24 11:34:30 +02:00
TRACE ( " (%p) \n " , This ) ;
2005-06-23 13:05:24 +02:00
2006-05-24 11:34:30 +02:00
return This - > NumberOfSwapChains ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain ( IWineD3DDevice * iface , UINT iSwapChain , IWineD3DSwapChain * * pSwapChain ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-11-10 13:14:56 +01:00
TRACE ( " (%p) : swapchain %d \n " , This , iSwapChain ) ;
2005-06-23 13:05:24 +02:00
2006-05-24 11:34:30 +02:00
if ( iSwapChain < This - > NumberOfSwapChains ) {
* pSwapChain = This - > swapchains [ iSwapChain ] ;
2006-11-30 13:33:11 +01:00
IWineD3DSwapChain_AddRef ( * pSwapChain ) ;
2006-05-24 11:34:30 +02:00
TRACE ( " (%p) returning %p \n " , This , * pSwapChain ) ;
return WINED3D_OK ;
} else {
TRACE ( " Swapchain out of range \n " ) ;
* pSwapChain = NULL ;
return WINED3DERR_INVALIDCALL ;
2005-07-27 17:33:17 +02:00
}
2005-03-02 13:16:10 +01:00
}
2009-09-20 20:09:24 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration ( IWineD3DDevice * iface ,
2009-09-23 10:05:52 +02:00
IWineD3DVertexDeclaration * * declaration , IUnknown * parent , const struct wined3d_parent_ops * parent_ops ,
2009-09-20 20:09:24 +02:00
const WINED3DVERTEXELEMENT * elements , UINT element_count )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-03-02 13:16:10 +01:00
IWineD3DVertexDeclarationImpl * object = NULL ;
2009-09-20 20:09:24 +02:00
HRESULT hr ;
2007-02-13 23:12:36 +01:00
2009-09-20 20:09:24 +02:00
TRACE ( " iface %p, declaration %p, parent %p, elements %p, element_count %u. \n " ,
iface , declaration , parent , elements , element_count ) ;
2007-02-13 23:12:36 +01:00
2009-01-14 10:01:11 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
2009-09-20 20:09:24 +02:00
ERR ( " Failed to allocate vertex declaration memory. \n " ) ;
return E_OUTOFMEMORY ;
2009-01-14 10:01:11 +01:00
}
2009-09-23 10:05:52 +02:00
hr = vertexdeclaration_init ( object , This , elements , element_count , parent , parent_ops ) ;
2009-09-20 20:09:24 +02:00
if ( FAILED ( hr ) )
{
WARN ( " Failed to initialize vertex declaration, hr %#x. \n " , hr ) ;
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
2007-12-20 20:48:03 +01:00
}
2005-03-02 13:16:10 +01:00
2009-10-26 10:12:18 +01:00
TRACE ( " Created vertex declaration %p. \n " , object ) ;
2009-09-20 20:09:24 +02:00
* declaration = ( IWineD3DVertexDeclaration * ) object ;
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2010-04-06 20:05:19 +02:00
struct wined3d_fvf_convert_state
{
const struct wined3d_gl_info * gl_info ;
WINED3DVERTEXELEMENT * elements ;
UINT offset ;
UINT idx ;
} ;
2007-04-25 17:04:46 +02:00
2010-04-06 20:05:19 +02:00
static void append_decl_element ( struct wined3d_fvf_convert_state * state ,
WINED3DFORMAT format , WINED3DDECLUSAGE usage , UINT usage_idx )
{
WINED3DVERTEXELEMENT * elements = state - > elements ;
const struct wined3d_format_desc * format_desc ;
UINT offset = state - > offset ;
UINT idx = state - > idx ;
elements [ idx ] . format = format ;
elements [ idx ] . input_slot = 0 ;
elements [ idx ] . offset = offset ;
elements [ idx ] . output_slot = 0 ;
elements [ idx ] . method = WINED3DDECLMETHOD_DEFAULT ;
elements [ idx ] . usage = usage ;
elements [ idx ] . usage_idx = usage_idx ;
format_desc = getFormatDescEntry ( format , state - > gl_info ) ;
state - > offset + = format_desc - > component_count * format_desc - > component_size ;
+ + state - > idx ;
}
static unsigned int ConvertFvfToDeclaration ( IWineD3DDeviceImpl * This , /* For the GL info, which has the type table */
DWORD fvf , WINED3DVERTEXELEMENT * * ppVertexElements )
{
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2007-04-25 17:04:46 +02:00
BOOL has_pos = ( fvf & WINED3DFVF_POSITION_MASK ) ! = 0 ;
BOOL has_blend = ( fvf & WINED3DFVF_XYZB5 ) > WINED3DFVF_XYZRHW ;
BOOL has_blend_idx = has_blend & &
( ( ( fvf & WINED3DFVF_XYZB5 ) = = WINED3DFVF_XYZB5 ) | |
( fvf & WINED3DFVF_LASTBETA_D3DCOLOR ) | |
( fvf & WINED3DFVF_LASTBETA_UBYTE4 ) ) ;
BOOL has_normal = ( fvf & WINED3DFVF_NORMAL ) ! = 0 ;
BOOL has_psize = ( fvf & WINED3DFVF_PSIZE ) ! = 0 ;
BOOL has_diffuse = ( fvf & WINED3DFVF_DIFFUSE ) ! = 0 ;
BOOL has_specular = ( fvf & WINED3DFVF_SPECULAR ) ! = 0 ;
DWORD num_textures = ( fvf & WINED3DFVF_TEXCOUNT_MASK ) > > WINED3DFVF_TEXCOUNT_SHIFT ;
2008-08-20 17:51:45 +02:00
DWORD texcoords = ( fvf & 0xFFFF0000 ) > > 16 ;
2010-04-06 20:05:19 +02:00
struct wined3d_fvf_convert_state state ;
2007-04-25 17:04:46 +02:00
unsigned int size ;
2010-04-06 20:05:19 +02:00
unsigned int idx ;
2007-04-25 17:04:46 +02:00
DWORD num_blends = 1 + ( ( ( fvf & WINED3DFVF_XYZB5 ) - WINED3DFVF_XYZB1 ) > > 1 ) ;
if ( has_blend_idx ) num_blends - - ;
/* Compute declaration size */
size = has_pos + ( has_blend & & num_blends > 0 ) + has_blend_idx + has_normal +
2009-03-27 10:25:56 +01:00
has_psize + has_diffuse + has_specular + num_textures ;
2007-04-25 17:04:46 +02:00
2010-04-06 20:05:19 +02:00
state . gl_info = gl_info ;
state . elements = HeapAlloc ( GetProcessHeap ( ) , 0 , size * sizeof ( * state . elements ) ) ;
if ( ! state . elements ) return ~ 0U ;
state . offset = 0 ;
state . idx = 0 ;
2007-04-25 17:04:46 +02:00
2010-04-06 20:05:19 +02:00
if ( has_pos )
{
if ( ! has_blend & & ( fvf & WINED3DFVF_XYZRHW ) )
append_decl_element ( & state , WINED3DFMT_R32G32B32A32_FLOAT , WINED3DDECLUSAGE_POSITIONT , 0 ) ;
else if ( ( fvf & WINED3DFVF_XYZW ) = = WINED3DFVF_XYZW )
append_decl_element ( & state , WINED3DFMT_R32G32B32A32_FLOAT , WINED3DDECLUSAGE_POSITION , 0 ) ;
else
append_decl_element ( & state , WINED3DFMT_R32G32B32_FLOAT , WINED3DDECLUSAGE_POSITION , 0 ) ;
2007-04-25 17:04:46 +02:00
}
2010-04-06 20:05:19 +02:00
if ( has_blend & & ( num_blends > 0 ) )
{
if ( ( fvf & WINED3DFVF_XYZB5 ) = = WINED3DFVF_XYZB2 & & ( fvf & WINED3DFVF_LASTBETA_D3DCOLOR ) )
append_decl_element ( & state , WINED3DFMT_B8G8R8A8_UNORM , WINED3DDECLUSAGE_BLENDWEIGHT , 0 ) ;
else
{
switch ( num_blends )
{
case 1 :
append_decl_element ( & state , WINED3DFMT_R32_FLOAT , WINED3DDECLUSAGE_BLENDWEIGHT , 0 ) ;
break ;
case 2 :
append_decl_element ( & state , WINED3DFMT_R32G32_FLOAT , WINED3DDECLUSAGE_BLENDWEIGHT , 0 ) ;
break ;
case 3 :
append_decl_element ( & state , WINED3DFMT_R32G32B32_FLOAT , WINED3DDECLUSAGE_BLENDWEIGHT , 0 ) ;
break ;
case 4 :
append_decl_element ( & state , WINED3DFMT_R32G32B32A32_FLOAT , WINED3DDECLUSAGE_BLENDWEIGHT , 0 ) ;
break ;
2008-11-03 00:38:14 +01:00
default :
ERR ( " Unexpected amount of blend values: %u \n " , num_blends ) ;
}
}
2007-04-25 17:04:46 +02:00
}
2010-04-06 20:05:19 +02:00
if ( has_blend_idx )
{
if ( ( fvf & WINED3DFVF_LASTBETA_UBYTE4 )
| | ( ( fvf & WINED3DFVF_XYZB5 ) = = WINED3DFVF_XYZB2 & & ( fvf & WINED3DFVF_LASTBETA_D3DCOLOR ) ) )
append_decl_element ( & state , WINED3DFMT_R8G8B8A8_UINT , WINED3DDECLUSAGE_BLENDINDICES , 0 ) ;
2007-04-25 17:04:46 +02:00
else if ( fvf & WINED3DFVF_LASTBETA_D3DCOLOR )
2010-04-06 20:05:19 +02:00
append_decl_element ( & state , WINED3DFMT_B8G8R8A8_UNORM , WINED3DDECLUSAGE_BLENDINDICES , 0 ) ;
2007-04-25 17:04:46 +02:00
else
2010-04-06 20:05:19 +02:00
append_decl_element ( & state , WINED3DFMT_R32_FLOAT , WINED3DDECLUSAGE_BLENDINDICES , 0 ) ;
2007-04-25 17:04:46 +02:00
}
2010-04-06 20:05:19 +02:00
if ( has_normal ) append_decl_element ( & state , WINED3DFMT_R32G32B32_FLOAT , WINED3DDECLUSAGE_NORMAL , 0 ) ;
if ( has_psize ) append_decl_element ( & state , WINED3DFMT_R32_FLOAT , WINED3DDECLUSAGE_PSIZE , 0 ) ;
if ( has_diffuse ) append_decl_element ( & state , WINED3DFMT_B8G8R8A8_UNORM , WINED3DDECLUSAGE_COLOR , 0 ) ;
if ( has_specular ) append_decl_element ( & state , WINED3DFMT_B8G8R8A8_UNORM , WINED3DDECLUSAGE_COLOR , 1 ) ;
for ( idx = 0 ; idx < num_textures ; + + idx )
{
switch ( ( texcoords > > ( idx * 2 ) ) & 0x03 )
{
2007-04-25 17:04:46 +02:00
case WINED3DFVF_TEXTUREFORMAT1 :
2010-04-06 20:05:19 +02:00
append_decl_element ( & state , WINED3DFMT_R32_FLOAT , WINED3DDECLUSAGE_TEXCOORD , idx ) ;
2007-04-25 17:04:46 +02:00
break ;
case WINED3DFVF_TEXTUREFORMAT2 :
2010-04-06 20:05:19 +02:00
append_decl_element ( & state , WINED3DFMT_R32G32_FLOAT , WINED3DDECLUSAGE_TEXCOORD , idx ) ;
2007-04-25 17:04:46 +02:00
break ;
case WINED3DFVF_TEXTUREFORMAT3 :
2010-04-06 20:05:19 +02:00
append_decl_element ( & state , WINED3DFMT_R32G32B32_FLOAT , WINED3DDECLUSAGE_TEXCOORD , idx ) ;
2007-04-25 17:04:46 +02:00
break ;
case WINED3DFVF_TEXTUREFORMAT4 :
2010-04-06 20:05:19 +02:00
append_decl_element ( & state , WINED3DFMT_R32G32B32A32_FLOAT , WINED3DDECLUSAGE_TEXCOORD , idx ) ;
2007-04-25 17:04:46 +02:00
break ;
}
}
2010-04-06 20:05:19 +02:00
* ppVertexElements = state . elements ;
2007-04-25 17:04:46 +02:00
return size ;
}
2009-09-20 20:09:24 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF ( IWineD3DDevice * iface ,
2009-09-23 10:05:52 +02:00
IWineD3DVertexDeclaration * * declaration , IUnknown * parent ,
const struct wined3d_parent_ops * parent_ops , DWORD fvf )
2009-09-20 20:09:24 +02:00
{
2007-12-19 02:51:53 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-09-20 20:09:24 +02:00
WINED3DVERTEXELEMENT * elements ;
2008-01-07 17:17:04 +01:00
unsigned int size ;
2007-04-25 17:04:46 +02:00
DWORD hr ;
2009-09-20 20:09:24 +02:00
TRACE ( " iface %p, declaration %p, parent %p, fvf %#x. \n " , iface , declaration , parent , fvf ) ;
2007-04-25 17:04:46 +02:00
2009-09-20 20:09:24 +02:00
size = ConvertFvfToDeclaration ( This , fvf , & elements ) ;
if ( size = = ~ 0U ) return E_OUTOFMEMORY ;
2007-04-25 17:04:46 +02:00
2009-09-23 10:05:52 +02:00
hr = IWineD3DDevice_CreateVertexDeclaration ( iface , declaration , parent , parent_ops , elements , size ) ;
2009-09-20 20:09:24 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , elements ) ;
return hr ;
2007-04-22 11:52:11 +02:00
}
2009-05-26 09:15:12 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader ( IWineD3DDevice * iface ,
2009-05-28 08:44:21 +02:00
const DWORD * pFunction , const struct wined3d_shader_signature * output_signature ,
2009-09-23 18:42:08 +02:00
IWineD3DVertexShader * * ppVertexShader , IUnknown * parent ,
const struct wined3d_parent_ops * parent_ops )
2009-05-26 09:15:12 +02:00
{
2009-09-23 18:42:04 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DVertexShaderImpl * object ;
HRESULT hr ;
2008-12-15 16:35:13 +01:00
2009-01-12 10:17:50 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
2009-09-23 18:42:04 +02:00
ERR ( " Failed to allocate shader memory. \n " ) ;
return E_OUTOFMEMORY ;
2009-01-12 10:17:50 +01:00
}
2009-09-23 18:42:08 +02:00
hr = vertexshader_init ( object , This , pFunction , output_signature , parent , parent_ops ) ;
2009-01-12 10:17:50 +01:00
if ( FAILED ( hr ) )
{
2009-09-23 18:42:04 +02:00
WARN ( " Failed to initialize vertex shader, hr %#x. \n " , hr ) ;
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
2009-01-12 10:17:50 +01:00
return hr ;
2005-12-09 11:23:52 +01:00
}
2009-09-23 18:42:04 +02:00
TRACE ( " Created vertex shader %p. \n " , object ) ;
* ppVertexShader = ( IWineD3DVertexShader * ) object ;
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2010-01-03 21:18:23 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreateGeometryShader ( IWineD3DDevice * iface ,
const DWORD * byte_code , const struct wined3d_shader_signature * output_signature ,
IWineD3DGeometryShader * * shader , IUnknown * parent ,
const struct wined3d_parent_ops * parent_ops )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
struct wined3d_geometryshader * object ;
HRESULT hr ;
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Failed to allocate shader memory. \n " ) ;
return E_OUTOFMEMORY ;
}
hr = geometryshader_init ( object , This , byte_code , output_signature , parent , parent_ops ) ;
if ( FAILED ( hr ) )
{
WARN ( " Failed to initialize geometry shader, hr %#x. \n " , hr ) ;
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
}
TRACE ( " Created geometry shader %p. \n " , object ) ;
* shader = ( IWineD3DGeometryShader * ) object ;
return WINED3D_OK ;
}
2009-05-08 17:44:25 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader ( IWineD3DDevice * iface ,
const DWORD * pFunction , const struct wined3d_shader_signature * output_signature ,
2009-09-23 18:42:13 +02:00
IWineD3DPixelShader * * ppPixelShader , IUnknown * parent ,
const struct wined3d_parent_ops * parent_ops )
2009-05-08 17:44:25 +02:00
{
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-09-23 18:42:09 +02:00
IWineD3DPixelShaderImpl * object ;
HRESULT hr ;
2008-12-15 16:35:13 +01:00
2009-01-12 10:17:50 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
2009-09-23 18:42:09 +02:00
ERR ( " Failed to allocate shader memory. \n " ) ;
return E_OUTOFMEMORY ;
2009-01-12 10:17:50 +01:00
}
2009-09-23 18:42:13 +02:00
hr = pixelshader_init ( object , This , pFunction , output_signature , parent , parent_ops ) ;
2009-01-12 10:17:50 +01:00
if ( FAILED ( hr ) )
{
2009-09-23 18:42:09 +02:00
WARN ( " Failed to initialize pixel shader, hr %#x. \n " , hr ) ;
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
2009-01-12 10:17:50 +01:00
return hr ;
2005-11-21 17:27:55 +01:00
}
2005-08-25 21:24:21 +02:00
2009-09-23 18:42:09 +02:00
TRACE ( " Created pixel shader %p. \n " , object ) ;
* ppPixelShader = ( IWineD3DPixelShader * ) object ;
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2008-11-26 16:14:39 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette ( IWineD3DDevice * iface , DWORD Flags ,
const PALETTEENTRY * PalEnt , IWineD3DPalette * * Palette , IUnknown * Parent )
{
2006-04-17 17:04:59 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DPaletteImpl * object ;
2006-04-21 00:00:30 +02:00
HRESULT hr ;
2006-04-17 17:04:59 +02:00
2010-04-13 20:46:25 +02:00
TRACE ( " iface %p, flags %#x, entries %p, palette %p, parent %p. \n " ,
iface , Flags , PalEnt , Palette , Parent ) ;
2006-04-21 00:00:30 +02:00
2010-04-13 20:46:25 +02:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Failed to allocate palette memory. \n " ) ;
2006-04-21 00:00:30 +02:00
return E_OUTOFMEMORY ;
}
2010-04-13 20:46:25 +02:00
hr = wined3d_palette_init ( object , This , Flags , PalEnt , Parent ) ;
if ( FAILED ( hr ) )
{
WARN ( " Failed to initialize palette, hr %#x. \n " , hr ) ;
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
2006-04-21 00:00:30 +02:00
return hr ;
}
2006-04-17 17:04:59 +02:00
2010-04-13 20:46:25 +02:00
TRACE ( " Created palette %p. \n " , object ) ;
* Palette = ( IWineD3DPalette * ) object ;
2006-04-17 17:04:59 +02:00
2006-04-21 00:00:30 +02:00
return WINED3D_OK ;
2006-04-17 17:04:59 +02:00
}
2007-09-01 21:22:32 +02:00
static void IWineD3DDeviceImpl_LoadLogo ( IWineD3DDeviceImpl * This , const char * filename ) {
HBITMAP hbm ;
BITMAP bm ;
HRESULT hr ;
HDC dcb = NULL , dcs = NULL ;
WINEDDCOLORKEY colorkey ;
2009-02-03 09:36:07 +01:00
hbm = LoadImageA ( NULL , filename , IMAGE_BITMAP , 0 , 0 , LR_LOADFROMFILE | LR_CREATEDIBSECTION ) ;
2007-09-01 21:22:32 +02:00
if ( hbm )
{
GetObjectA ( hbm , sizeof ( BITMAP ) , & bm ) ;
dcb = CreateCompatibleDC ( NULL ) ;
if ( ! dcb ) goto out ;
SelectObject ( dcb , hbm ) ;
}
else
{
/* Create a 32x32 white surface to indicate that wined3d is used, but the specified image
* couldn ' t be loaded
*/
memset ( & bm , 0 , sizeof ( bm ) ) ;
bm . bmWidth = 32 ;
bm . bmHeight = 32 ;
}
2009-09-25 13:31:49 +02:00
hr = IWineD3DDevice_CreateSurface ( ( IWineD3DDevice * ) This , bm . bmWidth , bm . bmHeight , WINED3DFMT_B5G6R5_UNORM , TRUE ,
2009-09-16 08:37:15 +02:00
FALSE , 0 , & This - > logo_surface , 0 , WINED3DPOOL_DEFAULT , WINED3DMULTISAMPLE_NONE , 0 , SURFACE_OPENGL ,
NULL , & wined3d_null_parent_ops ) ;
2007-09-01 21:22:32 +02:00
if ( FAILED ( hr ) ) {
ERR ( " Wine logo requested, but failed to create surface \n " ) ;
goto out ;
}
if ( dcb ) {
hr = IWineD3DSurface_GetDC ( This - > logo_surface , & dcs ) ;
if ( FAILED ( hr ) ) goto out ;
BitBlt ( dcs , 0 , 0 , bm . bmWidth , bm . bmHeight , dcb , 0 , 0 , SRCCOPY ) ;
IWineD3DSurface_ReleaseDC ( This - > logo_surface , dcs ) ;
colorkey . dwColorSpaceLowValue = 0 ;
colorkey . dwColorSpaceHighValue = 0 ;
IWineD3DSurface_SetColorKey ( This - > logo_surface , WINEDDCKEY_SRCBLT , & colorkey ) ;
} else {
/* Fill the surface with a white color to show that wined3d is there */
IWineD3DDevice_ColorFill ( ( IWineD3DDevice * ) This , This - > logo_surface , NULL , 0xffffffff ) ;
}
2009-12-29 17:10:20 +01:00
out :
if ( dcb ) DeleteDC ( dcb ) ;
if ( hbm ) DeleteObject ( hbm ) ;
2007-09-01 21:22:32 +02:00
}
2009-06-26 10:07:12 +02:00
/* Context activation is done by the caller. */
2009-10-29 10:37:11 +01:00
static void create_dummy_textures ( IWineD3DDeviceImpl * This )
{
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2008-02-15 15:54:37 +01:00
unsigned int i ;
/* Under DirectX you can have texture stage operations even if no texture is
bound , whereas opengl will only do texture operations when a valid texture is
bound . We emulate this by creating dummy textures and binding them to each
texture stage , but disable all stages by default . Hence if a stage is enabled
then the default texture will kick in until replaced by a SetTexture call */
ENTER_GL ( ) ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ APPLE_CLIENT_STORAGE ] )
{
2008-02-15 15:54:37 +01:00
/* The dummy texture does not have client storage backing */
glPixelStorei ( GL_UNPACK_CLIENT_STORAGE_APPLE , GL_FALSE ) ;
checkGLcall ( " glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE) " ) ;
}
2009-10-22 10:09:54 +02:00
2009-10-29 10:37:11 +01:00
for ( i = 0 ; i < gl_info - > limits . textures ; + + i )
2009-10-22 10:09:54 +02:00
{
2008-02-15 15:54:37 +01:00
GLubyte white = 255 ;
/* Make appropriate texture active */
2008-12-16 13:18:49 +01:00
GL_EXTCALL ( glActiveTextureARB ( GL_TEXTURE0_ARB + i ) ) ;
checkGLcall ( " glActiveTextureARB " ) ;
2008-02-15 15:54:37 +01:00
/* Generate an opengl texture name */
glGenTextures ( 1 , & This - > dummyTextureName [ i ] ) ;
checkGLcall ( " glGenTextures " ) ;
TRACE ( " Dummy Texture %d given name %d \n " , i , This - > dummyTextureName [ i ] ) ;
/* Generate a dummy 2d texture (not using 1d because they cause many
* DRI drivers fall back to sw ) */
glBindTexture ( GL_TEXTURE_2D , This - > dummyTextureName [ i ] ) ;
checkGLcall ( " glBindTexture " ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_LUMINANCE , 1 , 1 , 0 , GL_LUMINANCE , GL_UNSIGNED_BYTE , & white ) ;
checkGLcall ( " glTexImage2D " ) ;
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ APPLE_CLIENT_STORAGE ] )
{
2008-02-15 15:54:37 +01:00
/* Reenable because if supported it is enabled by default */
glPixelStorei ( GL_UNPACK_CLIENT_STORAGE_APPLE , GL_TRUE ) ;
checkGLcall ( " glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE) " ) ;
}
LEAVE_GL ( ) ;
}
2009-12-17 19:14:34 +01:00
/* Context activation is done by the caller. */
static void destroy_dummy_textures ( IWineD3DDeviceImpl * device , const struct wined3d_gl_info * gl_info )
{
ENTER_GL ( ) ;
glDeleteTextures ( gl_info - > limits . textures , device - > dummyTextureName ) ;
checkGLcall ( " glDeleteTextures(gl_info->limits.textures, device->dummyTextureName) " ) ;
LEAVE_GL ( ) ;
memset ( device - > dummyTextureName , 0 , gl_info - > limits . textures * sizeof ( * device - > dummyTextureName ) ) ;
}
2010-03-17 21:59:49 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_AcquireFocusWindow ( IWineD3DDevice * iface , HWND window )
{
IWineD3DDeviceImpl * device = ( IWineD3DDeviceImpl * ) iface ;
if ( ! wined3d_register_window ( window , device ) )
{
ERR ( " Failed to register window %p. \n " , window ) ;
return E_FAIL ;
}
device - > focus_window = window ;
SetForegroundWindow ( window ) ;
return WINED3D_OK ;
}
static void WINAPI IWineD3DDeviceImpl_ReleaseFocusWindow ( IWineD3DDevice * iface )
{
IWineD3DDeviceImpl * device = ( IWineD3DDeviceImpl * ) iface ;
if ( device - > focus_window ) wined3d_unregister_window ( device - > focus_window ) ;
device - > focus_window = NULL ;
}
2009-01-16 10:14:24 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_Init3D ( IWineD3DDevice * iface ,
WINED3DPRESENT_PARAMETERS * pPresentationParameters )
{
2006-04-18 22:38:30 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-10-22 10:09:54 +02:00
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2008-01-22 09:27:00 +01:00
IWineD3DSwapChainImpl * swapchain = NULL ;
2009-10-28 11:00:12 +01:00
struct wined3d_context * context ;
2007-06-12 17:49:58 +02:00
HRESULT hr ;
2006-12-15 19:16:36 +01:00
DWORD state ;
2008-03-26 23:23:04 +01:00
unsigned int i ;
2006-04-18 22:38:30 +02:00
2009-01-16 10:14:24 +01:00
TRACE ( " (%p)->(%p) \n " , This , pPresentationParameters ) ;
2006-04-18 22:38:30 +02:00
if ( This - > d3d_initialized ) return WINED3DERR_INVALIDCALL ;
2008-03-28 23:04:52 +01:00
if ( ! This - > adapter - > opengl ) return WINED3DERR_INVALIDCALL ;
2006-04-18 22:38:30 +02:00
2007-07-22 23:09:11 +02:00
TRACE ( " (%p) : Creating stateblock \n " , This ) ;
/* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
hr = IWineD3DDevice_CreateStateBlock ( iface ,
WINED3DSBT_INIT ,
( IWineD3DStateBlock * * ) & This - > stateBlock ,
NULL ) ;
if ( WINED3D_OK ! = hr ) { /* Note: No parent needed for initial internal stateblock */
WARN ( " Failed to create stateblock \n " ) ;
2007-10-09 22:04:18 +02:00
goto err_out ;
2007-07-22 23:09:11 +02:00
}
TRACE ( " (%p) : Created stateblock (%p) \n " , This , This - > stateBlock ) ;
This - > updateStateBlock = This - > stateBlock ;
IWineD3DStateBlock_AddRef ( ( IWineD3DStateBlock * ) This - > updateStateBlock ) ;
2009-10-22 10:09:54 +02:00
This - > render_targets = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY ,
2010-04-19 20:46:59 +02:00
sizeof ( * This - > render_targets ) * gl_info - > limits . buffers ) ;
2009-10-22 10:09:54 +02:00
This - > draw_buffers = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY ,
2009-10-29 10:37:10 +01:00
sizeof ( GLenum ) * gl_info - > limits . buffers ) ;
2007-07-16 19:49:34 +02:00
2008-03-26 23:23:04 +01:00
This - > NumberOfPalettes = 1 ;
This - > palettes = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( PALETTEENTRY * ) ) ;
2008-08-21 18:34:55 +02:00
if ( ! This - > palettes | | ! This - > render_targets | | ! This - > draw_buffers ) {
2008-03-26 23:23:04 +01:00
ERR ( " Out of memory! \n " ) ;
2009-12-02 10:41:20 +01:00
hr = E_OUTOFMEMORY ;
2008-03-26 23:23:04 +01:00
goto err_out ;
}
This - > palettes [ 0 ] = HeapAlloc ( GetProcessHeap ( ) , 0 , sizeof ( PALETTEENTRY ) * 256 ) ;
if ( ! This - > palettes [ 0 ] ) {
ERR ( " Out of memory! \n " ) ;
2009-12-02 10:41:20 +01:00
hr = E_OUTOFMEMORY ;
2008-03-26 23:23:04 +01:00
goto err_out ;
}
for ( i = 0 ; i < 256 ; + + i ) {
This - > palettes [ 0 ] [ i ] . peRed = 0xFF ;
This - > palettes [ 0 ] [ i ] . peGreen = 0xFF ;
This - > palettes [ 0 ] [ i ] . peBlue = 0xFF ;
This - > palettes [ 0 ] [ i ] . peFlags = 0xFF ;
}
This - > currentPalette = 0 ;
2006-12-19 23:33:34 +01:00
/* Initialize the texture unit mapping to a 1:1 mapping */
2009-10-22 10:09:54 +02:00
for ( state = 0 ; state < MAX_COMBINED_SAMPLERS ; + + state )
{
2009-10-29 10:37:10 +01:00
if ( state < gl_info - > limits . fragment_samplers )
2009-10-22 10:09:54 +02:00
{
2007-06-22 20:43:19 +02:00
This - > texUnitMap [ state ] = state ;
This - > rev_tex_unit_map [ state ] = state ;
} else {
2009-08-17 09:39:07 +02:00
This - > texUnitMap [ state ] = WINED3D_UNMAPPED_STAGE ;
This - > rev_tex_unit_map [ state ] = WINED3D_UNMAPPED_STAGE ;
2007-06-22 20:43:19 +02:00
}
2006-12-19 23:33:34 +01:00
}
2009-06-26 10:07:12 +02:00
/* Setup the implicit swapchain. This also initializes a context. */
2006-04-18 22:38:30 +02:00
TRACE ( " Creating implicit swapchain \n " ) ;
2009-01-16 10:14:24 +01:00
hr = IWineD3DDeviceParent_CreateSwapChain ( This - > device_parent ,
pPresentationParameters , ( IWineD3DSwapChain * * ) & swapchain ) ;
if ( FAILED ( hr ) )
{
2006-04-18 22:38:30 +02:00
WARN ( " Failed to create implicit swapchain \n " ) ;
2007-10-09 22:04:18 +02:00
goto err_out ;
2006-04-18 22:38:30 +02:00
}
2006-05-24 11:34:30 +02:00
This - > NumberOfSwapChains = 1 ;
This - > swapchains = HeapAlloc ( GetProcessHeap ( ) , 0 , This - > NumberOfSwapChains * sizeof ( IWineD3DSwapChain * ) ) ;
if ( ! This - > swapchains ) {
ERR ( " Out of memory! \n " ) ;
2007-10-09 22:04:18 +02:00
goto err_out ;
2006-05-24 11:34:30 +02:00
}
This - > swapchains [ 0 ] = ( IWineD3DSwapChain * ) swapchain ;
2010-04-26 21:33:01 +02:00
if ( swapchain - > back_buffers & & swapchain - > back_buffers [ 0 ] )
{
TRACE ( " Setting rendertarget to %p. \n " , swapchain - > back_buffers ) ;
This - > render_targets [ 0 ] = swapchain - > back_buffers [ 0 ] ;
2006-04-18 22:38:30 +02:00
}
2010-04-26 21:33:00 +02:00
else
{
TRACE ( " Setting rendertarget to %p. \n " , swapchain - > front_buffer ) ;
This - > render_targets [ 0 ] = swapchain - > front_buffer ;
2006-04-18 22:38:30 +02:00
}
2010-04-19 20:46:59 +02:00
IWineD3DSurface_AddRef ( ( IWineD3DSurface * ) This - > render_targets [ 0 ] ) ;
2007-02-12 19:21:10 +01:00
2006-04-18 22:38:30 +02:00
/* Depth Stencil support */
2010-04-19 20:47:01 +02:00
This - > depth_stencil = This - > auto_depth_stencil ;
if ( This - > depth_stencil )
IWineD3DSurface_AddRef ( ( IWineD3DSurface * ) This - > depth_stencil ) ;
2006-04-18 22:38:30 +02:00
2008-03-18 19:49:05 +01:00
hr = This - > shader_backend - > shader_alloc_private ( iface ) ;
if ( FAILED ( hr ) ) {
TRACE ( " Shader private data couldn't be allocated \n " ) ;
goto err_out ;
}
2008-07-11 16:41:28 +02:00
hr = This - > frag_pipe - > alloc_private ( iface ) ;
if ( FAILED ( hr ) ) {
TRACE ( " Fragment pipeline private data couldn't be allocated \n " ) ;
goto err_out ;
}
2008-08-01 20:21:10 +02:00
hr = This - > blitter - > alloc_private ( iface ) ;
if ( FAILED ( hr ) ) {
TRACE ( " Blitter private data couldn't be allocated \n " ) ;
goto err_out ;
}
2008-03-18 19:49:05 +01:00
2006-04-18 22:38:30 +02:00
/* Set up some starting GL setup */
/* Setup all the devices defaults */
IWineD3DStateBlock_InitStartupStateBlock ( ( IWineD3DStateBlock * ) This - > stateBlock ) ;
2009-10-28 11:00:12 +01:00
2010-04-26 21:33:00 +02:00
context = context_acquire ( This , swapchain - > front_buffer , CTXUSAGE_RESOURCELOAD ) ;
2009-10-28 11:00:12 +01:00
2008-02-15 15:54:37 +01:00
create_dummy_textures ( This ) ;
2008-04-06 23:06:22 +02:00
ENTER_GL ( ) ;
2006-04-18 22:38:30 +02:00
/* Initialize the current view state */
This - > view_ident = 1 ;
2007-02-12 19:35:45 +01:00
This - > contexts [ 0 ] - > last_was_rhw = 0 ;
2006-04-18 22:38:30 +02:00
glGetIntegerv ( GL_MAX_LIGHTS , & This - > maxConcurrentLights ) ;
2007-02-12 19:22:41 +01:00
checkGLcall ( " glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights) " ) ;
2007-02-27 21:32:15 +01:00
switch ( wined3d_settings . offscreen_rendering_mode ) {
case ORM_FBO :
2009-12-04 10:21:01 +01:00
This - > offscreenBuffer = GL_COLOR_ATTACHMENT0 ;
break ;
2007-02-27 21:32:15 +01:00
case ORM_BACKBUFFER :
{
2009-07-24 10:44:17 +02:00
if ( context_get_current ( ) - > aux_buffers > 0 )
{
2007-02-27 21:32:15 +01:00
TRACE ( " Using auxilliary buffer for offscreen rendering \n " ) ;
This - > offscreenBuffer = GL_AUX0 ;
} else {
TRACE ( " Using back buffer for offscreen rendering \n " ) ;
This - > offscreenBuffer = GL_BACK ;
}
}
}
2006-04-18 22:38:30 +02:00
TRACE ( " (%p) All defaults now set up, leaving Init3D with %p \n " , This , This ) ;
2007-02-12 19:22:41 +01:00
LEAVE_GL ( ) ;
2006-04-18 22:38:30 +02:00
2009-10-28 11:00:12 +01:00
context_release ( context ) ;
2006-04-18 22:38:30 +02:00
/* Clear the screen */
2007-03-06 13:35:56 +01:00
IWineD3DDevice_Clear ( ( IWineD3DDevice * ) This , 0 , NULL ,
WINED3DCLEAR_TARGET | pPresentationParameters - > EnableAutoDepthStencil ? WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL : 0 ,
2009-07-07 11:08:01 +02:00
0x00 , 1.0f , 0 ) ;
2006-04-18 22:38:30 +02:00
This - > d3d_initialized = TRUE ;
2007-09-01 21:22:32 +02:00
if ( wined3d_settings . logo ) {
IWineD3DDeviceImpl_LoadLogo ( This , wined3d_settings . logo ) ;
}
2008-03-04 02:30:23 +01:00
This - > highest_dirty_ps_const = 0 ;
This - > highest_dirty_vs_const = 0 ;
2006-04-18 22:38:30 +02:00
return WINED3D_OK ;
2007-10-09 22:04:18 +02:00
2008-01-22 09:27:00 +01:00
err_out :
2007-10-09 22:04:18 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , This - > render_targets ) ;
HeapFree ( GetProcessHeap ( ) , 0 , This - > draw_buffers ) ;
HeapFree ( GetProcessHeap ( ) , 0 , This - > swapchains ) ;
This - > NumberOfSwapChains = 0 ;
2008-03-26 23:23:04 +01:00
if ( This - > palettes ) {
HeapFree ( GetProcessHeap ( ) , 0 , This - > palettes [ 0 ] ) ;
HeapFree ( GetProcessHeap ( ) , 0 , This - > palettes ) ;
}
This - > NumberOfPalettes = 0 ;
2007-10-09 22:04:18 +02:00
if ( swapchain ) {
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
}
if ( This - > stateBlock ) {
IWineD3DStateBlock_Release ( ( IWineD3DStateBlock * ) This - > stateBlock ) ;
This - > stateBlock = NULL ;
}
2008-08-20 22:45:02 +02:00
if ( This - > blit_priv ) {
This - > blitter - > free_private ( iface ) ;
}
if ( This - > fragment_priv ) {
This - > frag_pipe - > free_private ( iface ) ;
}
if ( This - > shader_priv ) {
This - > shader_backend - > shader_free_private ( iface ) ;
}
2007-10-09 22:04:18 +02:00
return hr ;
2006-04-12 21:08:57 +02:00
}
2009-01-16 10:14:24 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_InitGDI ( IWineD3DDevice * iface ,
WINED3DPRESENT_PARAMETERS * pPresentationParameters )
{
2008-08-05 21:23:00 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DSwapChainImpl * swapchain = NULL ;
HRESULT hr ;
/* Setup the implicit swapchain */
TRACE ( " Creating implicit swapchain \n " ) ;
2009-01-16 10:14:24 +01:00
hr = IWineD3DDeviceParent_CreateSwapChain ( This - > device_parent ,
pPresentationParameters , ( IWineD3DSwapChain * * ) & swapchain ) ;
if ( FAILED ( hr ) )
{
2008-08-05 21:23:00 +02:00
WARN ( " Failed to create implicit swapchain \n " ) ;
goto err_out ;
}
This - > NumberOfSwapChains = 1 ;
This - > swapchains = HeapAlloc ( GetProcessHeap ( ) , 0 , This - > NumberOfSwapChains * sizeof ( IWineD3DSwapChain * ) ) ;
if ( ! This - > swapchains ) {
ERR ( " Out of memory! \n " ) ;
goto err_out ;
}
This - > swapchains [ 0 ] = ( IWineD3DSwapChain * ) swapchain ;
return WINED3D_OK ;
err_out :
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
return hr ;
}
2009-03-23 13:54:34 +01:00
static HRESULT WINAPI device_unload_resource ( IWineD3DResource * resource , void * ctx )
{
IWineD3DResource_UnLoad ( resource ) ;
IWineD3DResource_Release ( resource ) ;
return WINED3D_OK ;
}
2009-09-16 08:37:15 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D ( IWineD3DDevice * iface ,
D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain )
{
2006-04-18 22:38:30 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-09-23 10:05:55 +02:00
const struct wined3d_gl_info * gl_info ;
2009-10-28 11:00:11 +01:00
struct wined3d_context * context ;
2006-06-27 23:40:42 +02:00
int sampler ;
2007-08-06 16:38:00 +02:00
UINT i ;
2006-04-18 22:38:30 +02:00
TRACE ( " (%p) \n " , This ) ;
if ( ! This - > d3d_initialized ) return WINED3DERR_INVALIDCALL ;
2008-01-09 20:37:05 +01:00
/* I don't think that the interface guarantees that the device is destroyed from the same thread
2007-03-17 23:00:39 +01:00
* it was created . Thus make sure a context is active for the glDelete * calls
*/
2009-10-28 11:00:11 +01:00
context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2009-09-23 10:05:55 +02:00
gl_info = context - > gl_info ;
2007-03-17 23:00:39 +01:00
2007-09-01 21:22:32 +02:00
if ( This - > logo_surface ) IWineD3DSurface_Release ( This - > logo_surface ) ;
2009-03-23 13:54:34 +01:00
/* Unload resources */
IWineD3DDevice_EnumResources ( iface , device_unload_resource , NULL ) ;
2007-07-04 17:57:45 +02:00
TRACE ( " Deleting high order patches \n " ) ;
for ( i = 0 ; i < PATCHMAP_SIZE ; i + + ) {
struct list * e1 , * e2 ;
struct WineD3DRectPatch * patch ;
LIST_FOR_EACH_SAFE ( e1 , e2 , & This - > patches [ i ] ) {
patch = LIST_ENTRY ( e1 , struct WineD3DRectPatch , entry ) ;
IWineD3DDevice_DeletePatch ( iface , patch - > Handle ) ;
}
}
2006-07-27 17:39:03 +02:00
/* Delete the mouse cursor texture */
if ( This - > cursorTexture ) {
ENTER_GL ( ) ;
glDeleteTextures ( 1 , & This - > cursorTexture ) ;
LEAVE_GL ( ) ;
This - > cursorTexture = 0 ;
}
2007-06-25 22:45:40 +02:00
for ( sampler = 0 ; sampler < MAX_FRAGMENT_SAMPLERS ; + + sampler ) {
2006-06-27 23:40:42 +02:00
IWineD3DDevice_SetTexture ( iface , sampler , NULL ) ;
2006-04-18 22:38:30 +02:00
}
2007-06-25 22:45:40 +02:00
for ( sampler = 0 ; sampler < MAX_VERTEX_SAMPLERS ; + + sampler ) {
IWineD3DDevice_SetTexture ( iface , WINED3DVERTEXTEXTURESAMPLER0 + sampler , NULL ) ;
}
2006-04-18 22:38:30 +02:00
2008-03-18 19:49:05 +01:00
/* Destroy the depth blt resources, they will be invalid after the reset. Also free shader
* private data , it might contain opengl pointers
*/
2008-06-27 00:52:13 +02:00
if ( This - > depth_blt_texture ) {
2009-05-13 18:22:55 +02:00
ENTER_GL ( ) ;
2008-06-27 00:52:13 +02:00
glDeleteTextures ( 1 , & This - > depth_blt_texture ) ;
2009-05-13 18:22:55 +02:00
LEAVE_GL ( ) ;
2008-06-27 00:52:13 +02:00
This - > depth_blt_texture = 0 ;
}
2008-07-02 23:00:11 +02:00
if ( This - > depth_blt_rb ) {
2009-05-13 18:22:55 +02:00
ENTER_GL ( ) ;
2009-09-23 10:05:55 +02:00
gl_info - > fbo_ops . glDeleteRenderbuffers ( 1 , & This - > depth_blt_rb ) ;
2009-05-13 18:22:55 +02:00
LEAVE_GL ( ) ;
2008-07-02 23:00:11 +02:00
This - > depth_blt_rb = 0 ;
This - > depth_blt_rb_w = 0 ;
This - > depth_blt_rb_h = 0 ;
}
2008-03-18 19:49:05 +01:00
2007-08-14 14:44:41 +02:00
/* Release the update stateblock */
if ( IWineD3DStateBlock_Release ( ( IWineD3DStateBlock * ) This - > updateStateBlock ) > 0 ) {
if ( This - > updateStateBlock ! = This - > stateBlock )
FIXME ( " (%p) Something's still holding the Update stateblock \n " , This ) ;
}
This - > updateStateBlock = NULL ;
{ /* because were not doing proper internal refcounts releasing the primary state block
causes recursion with the extra checks in ResourceReleased , to avoid this we have
to set this - > stateBlock = NULL ; first */
IWineD3DStateBlock * stateBlock = ( IWineD3DStateBlock * ) This - > stateBlock ;
This - > stateBlock = NULL ;
/* Release the stateblock */
if ( IWineD3DStateBlock_Release ( stateBlock ) > 0 ) {
FIXME ( " (%p) Something's still holding the Update stateblock \n " , This ) ;
}
}
2008-07-10 23:26:10 +02:00
/* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */
2008-08-01 20:21:10 +02:00
This - > blitter - > free_private ( iface ) ;
2008-07-11 16:41:28 +02:00
This - > frag_pipe - > free_private ( iface ) ;
2008-07-28 18:41:02 +02:00
This - > shader_backend - > shader_free_private ( iface ) ;
2008-07-10 23:26:10 +02:00
2006-05-24 11:34:30 +02:00
/* Release the buffers (with sanity checks)*/
2010-04-20 22:38:41 +02:00
if ( This - > onscreen_depth_stencil )
{
IWineD3DSurface_Release ( ( IWineD3DSurface * ) This - > onscreen_depth_stencil ) ;
This - > onscreen_depth_stencil = NULL ;
}
2010-04-19 20:47:01 +02:00
TRACE ( " Releasing the depth stencil buffer at %p \n " , This - > depth_stencil ) ;
if ( This - > depth_stencil & & IWineD3DSurface_Release ( ( IWineD3DSurface * ) This - > depth_stencil ) )
2010-04-19 20:47:00 +02:00
{
2010-04-19 20:47:01 +02:00
if ( This - > auto_depth_stencil ! = This - > depth_stencil )
FIXME ( " (%p) Something is still holding the depth/stencil buffer. \n " , This ) ;
2006-04-18 22:38:30 +02:00
}
2010-04-19 20:47:01 +02:00
This - > depth_stencil = NULL ;
2006-04-18 22:38:30 +02:00
2006-12-19 19:25:22 +01:00
TRACE ( " Releasing the render target at %p \n " , This - > render_targets [ 0 ] ) ;
2010-04-19 20:46:59 +02:00
IWineD3DSurface_Release ( ( IWineD3DSurface * ) This - > render_targets [ 0 ] ) ;
2010-04-15 19:21:29 +02:00
2006-04-18 22:38:30 +02:00
TRACE ( " Setting rendertarget to NULL \n " ) ;
2006-12-19 19:25:22 +01:00
This - > render_targets [ 0 ] = NULL ;
2006-04-18 22:38:30 +02:00
2010-04-19 20:47:00 +02:00
if ( This - > auto_depth_stencil )
{
if ( IWineD3DSurface_Release ( ( IWineD3DSurface * ) This - > auto_depth_stencil ) )
2009-09-16 08:37:15 +02:00
{
2007-11-10 00:19:19 +01:00
FIXME ( " (%p) Something's still holding the auto depth stencil buffer \n " , This ) ;
2006-07-21 05:06:32 +02:00
}
2010-04-19 20:47:00 +02:00
This - > auto_depth_stencil = NULL ;
2006-04-18 22:38:30 +02:00
}
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2006-05-24 11:34:30 +02:00
for ( i = 0 ; i < This - > NumberOfSwapChains ; i + + ) {
TRACE ( " Releasing the implicit swapchain %d \n " , i ) ;
2006-12-18 00:17:24 +01:00
if ( D3DCB_DestroySwapChain ( This - > swapchains [ i ] ) > 0 ) {
2006-04-18 22:38:30 +02:00
FIXME ( " (%p) Something's still holding the implicit swapchain \n " , This ) ;
}
}
2006-05-24 11:34:30 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , This - > swapchains ) ;
2006-04-18 22:38:30 +02:00
This - > swapchains = NULL ;
2006-05-24 11:34:30 +02:00
This - > NumberOfSwapChains = 0 ;
2006-04-18 22:38:30 +02:00
2008-03-26 23:23:04 +01:00
for ( i = 0 ; i < This - > NumberOfPalettes ; i + + ) HeapFree ( GetProcessHeap ( ) , 0 , This - > palettes [ i ] ) ;
HeapFree ( GetProcessHeap ( ) , 0 , This - > palettes ) ;
This - > palettes = NULL ;
This - > NumberOfPalettes = 0 ;
2007-07-16 19:49:34 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , This - > render_targets ) ;
HeapFree ( GetProcessHeap ( ) , 0 , This - > draw_buffers ) ;
This - > render_targets = NULL ;
This - > draw_buffers = NULL ;
2006-04-18 22:38:30 +02:00
This - > d3d_initialized = FALSE ;
2009-12-22 18:32:13 +01:00
2006-04-18 22:38:30 +02:00
return WINED3D_OK ;
2006-04-12 21:08:57 +02:00
}
2008-08-05 21:23:00 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_UninitGDI ( IWineD3DDevice * iface , D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain ) {
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
unsigned int i ;
for ( i = 0 ; i < This - > NumberOfSwapChains ; i + + ) {
TRACE ( " Releasing the implicit swapchain %d \n " , i ) ;
if ( D3DCB_DestroySwapChain ( This - > swapchains [ i ] ) > 0 ) {
FIXME ( " (%p) Something's still holding the implicit swapchain \n " , This ) ;
}
}
HeapFree ( GetProcessHeap ( ) , 0 , This - > swapchains ) ;
This - > swapchains = NULL ;
This - > NumberOfSwapChains = 0 ;
return WINED3D_OK ;
}
2007-10-19 05:40:40 +02:00
/* Enables thread safety in the wined3d device and its resources. Called by DirectDraw
* from SetCooperativeLevel if DDSCL_MULTITHREADED is specified , and by d3d8 / 9 from
2007-03-04 17:03:03 +01:00
* CreateDevice if D3DCREATE_MULTITHREADED is passed .
*
2007-10-19 05:40:40 +02:00
* There is no way to deactivate thread safety once it is enabled .
2007-03-04 17:03:03 +01:00
*/
static void WINAPI IWineD3DDeviceImpl_SetMultithreaded ( IWineD3DDevice * iface ) {
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
/*For now just store the flag(needed in case of ddraw) */
This - > createParms . BehaviorFlags | = WINED3DCREATE_MULTITHREADED ;
}
2008-11-25 11:57:39 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode ( IWineD3DDevice * iface , UINT iSwapChain ,
const WINED3DDISPLAYMODE * pMode ) {
2006-05-18 22:42:22 +02:00
DEVMODEW devmode ;
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * format_desc = getFormatDescEntry ( pMode - > Format , & This - > adapter - > gl_info ) ;
2006-05-18 22:42:22 +02:00
LONG ret ;
2006-12-14 23:51:23 +01:00
RECT clip_rc ;
2006-05-18 22:42:22 +02:00
TRACE ( " (%p)->(%d,%p) Mode=%dx%dx@%d, %s \n " , This , iSwapChain , pMode , pMode - > Width , pMode - > Height , pMode - > RefreshRate , debug_d3dformat ( pMode - > Format ) ) ;
/* Resize the screen even without a window:
* The app could have unset it with SetCooperativeLevel , but not called
* RestoreDisplayMode first . Then the release will call RestoreDisplayMode ,
* but we don ' t have any hwnd
*/
2007-08-05 20:23:42 +02:00
memset ( & devmode , 0 , sizeof ( devmode ) ) ;
devmode . dmSize = sizeof ( devmode ) ;
2006-05-18 22:42:22 +02:00
devmode . dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT ;
2009-03-13 10:44:18 +01:00
devmode . dmBitsPerPel = format_desc - > byte_count * 8 ;
2006-05-18 22:42:22 +02:00
devmode . dmPelsWidth = pMode - > Width ;
devmode . dmPelsHeight = pMode - > Height ;
devmode . dmDisplayFrequency = pMode - > RefreshRate ;
if ( pMode - > RefreshRate ! = 0 ) {
devmode . dmFields | = DM_DISPLAYFREQUENCY ;
}
/* Only change the mode if necessary */
if ( ( This - > ddraw_width = = pMode - > Width ) & &
( This - > ddraw_height = = pMode - > Height ) & &
( This - > ddraw_format = = pMode - > Format ) & &
( pMode - > RefreshRate = = 0 ) ) {
2007-02-14 23:30:40 +01:00
return WINED3D_OK ;
2006-05-18 22:42:22 +02:00
}
ret = ChangeDisplaySettingsExW ( NULL , & devmode , NULL , CDS_FULLSCREEN , NULL ) ;
if ( ret ! = DISP_CHANGE_SUCCESSFUL ) {
if ( devmode . dmDisplayFrequency ! = 0 ) {
WARN ( " ChangeDisplaySettingsExW failed, trying without the refresh rate \n " ) ;
devmode . dmFields & = ~ DM_DISPLAYFREQUENCY ;
devmode . dmDisplayFrequency = 0 ;
ret = ChangeDisplaySettingsExW ( NULL , & devmode , NULL , CDS_FULLSCREEN , NULL ) ! = DISP_CHANGE_SUCCESSFUL ;
}
if ( ret ! = DISP_CHANGE_SUCCESSFUL ) {
2007-04-14 22:44:55 +02:00
return WINED3DERR_NOTAVAILABLE ;
2006-05-18 22:42:22 +02:00
}
}
/* Store the new values */
This - > ddraw_width = pMode - > Width ;
This - > ddraw_height = pMode - > Height ;
This - > ddraw_format = pMode - > Format ;
2006-12-14 23:51:23 +01:00
/* And finally clip mouse to our screen */
SetRect ( & clip_rc , 0 , 0 , pMode - > Width , pMode - > Height ) ;
ClipCursor ( & clip_rc ) ;
2006-05-18 22:42:22 +02:00
return WINED3D_OK ;
2006-04-17 17:51:21 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetDirect3D ( IWineD3DDevice * iface , IWineD3D * * ppD3D ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-12-07 20:20:02 +01:00
* ppD3D = This - > wined3d ;
TRACE ( " Returning %p. \n " , * ppD3D ) ;
2006-11-30 13:32:58 +01:00
IWineD3D_AddRef ( * ppD3D ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-07-13 16:15:54 +02:00
2006-06-10 13:15:32 +02:00
static UINT WINAPI IWineD3DDeviceImpl_GetAvailableTextureMem ( IWineD3DDevice * iface ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-09-23 00:46:21 +02:00
2006-08-08 00:03:06 +02:00
TRACE ( " (%p) : simulating %dMB, returning %dMB left \n " , This ,
2007-09-23 00:46:21 +02:00
( This - > adapter - > TextureRam / ( 1024 * 1024 ) ) ,
( ( This - > adapter - > TextureRam - This - > adapter - > UsedTextureRam ) / ( 1024 * 1024 ) ) ) ;
2006-08-08 00:03:06 +02:00
/* return simulated texture memory left */
2007-09-23 00:46:21 +02:00
return ( This - > adapter - > TextureRam - This - > adapter - > UsedTextureRam ) ;
2005-03-02 13:16:10 +01:00
}
2004-11-23 14:52:46 +01:00
/*****
* Get / Set Stream Source
* * * * */
2009-03-06 14:56:23 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource ( IWineD3DDevice * iface , UINT StreamNumber ,
IWineD3DBuffer * pStreamData , UINT OffsetInBytes , UINT Stride )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DBuffer * oldSrc ;
2004-11-23 14:52:46 +01:00
2005-09-02 13:17:17 +02:00
if ( StreamNumber > = MAX_STREAMS ) {
WARN ( " Stream out of range %d \n " , StreamNumber ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2007-12-20 22:14:53 +01:00
} else if ( OffsetInBytes & 0x3 ) {
WARN ( " OffsetInBytes is not 4 byte aligned: %d \n " , OffsetInBytes ) ;
return WINED3DERR_INVALIDCALL ;
2005-09-02 13:17:17 +02:00
}
2007-08-19 20:37:50 +02:00
oldSrc = This - > updateStateBlock - > streamSource [ StreamNumber ] ;
2007-04-09 01:55:16 +02:00
TRACE ( " (%p) : StreamNo: %u, OldStream (%p), NewStream (%p), OffsetInBytes %u, NewStride %u \n " , This , StreamNumber , oldSrc , pStreamData , OffsetInBytes , Stride ) ;
2004-11-23 14:52:46 +01:00
2008-12-31 16:57:11 +01:00
This - > updateStateBlock - > changed . streamSource | = 1 < < StreamNumber ;
2007-01-04 00:08:20 +01:00
if ( oldSrc = = pStreamData & &
This - > updateStateBlock - > streamStride [ StreamNumber ] = = Stride & &
2007-02-14 17:49:53 +01:00
This - > updateStateBlock - > streamOffset [ StreamNumber ] = = OffsetInBytes ) {
2007-01-04 00:08:20 +01:00
TRACE ( " Application is setting the old values over, nothing to do \n " ) ;
return WINED3D_OK ;
}
2005-07-05 16:05:18 +02:00
This - > updateStateBlock - > streamSource [ StreamNumber ] = pStreamData ;
2006-12-24 10:00:05 +01:00
if ( pStreamData ) {
This - > updateStateBlock - > streamStride [ StreamNumber ] = Stride ;
This - > updateStateBlock - > streamOffset [ StreamNumber ] = OffsetInBytes ;
}
2004-11-23 14:52:46 +01:00
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2009-03-06 14:56:23 +01:00
if ( pStreamData ) IWineD3DBuffer_AddRef ( pStreamData ) ;
if ( oldSrc ) IWineD3DBuffer_Release ( oldSrc ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-23 14:52:46 +01:00
}
2005-07-26 20:49:30 +02:00
if ( pStreamData ! = NULL ) {
2009-03-06 14:56:23 +01:00
InterlockedIncrement ( & ( ( struct wined3d_buffer * ) pStreamData ) - > bind_count ) ;
IWineD3DBuffer_AddRef ( pStreamData ) ;
2005-07-26 20:49:30 +02:00
}
if ( oldSrc ! = NULL ) {
2009-03-06 14:56:23 +01:00
InterlockedDecrement ( & ( ( struct wined3d_buffer * ) oldSrc ) - > bind_count ) ;
IWineD3DBuffer_Release ( oldSrc ) ;
2005-07-26 20:49:30 +02:00
}
2004-11-23 14:52:46 +01:00
2007-01-02 00:35:07 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_STREAMSRC ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-23 14:52:46 +01:00
}
2009-03-06 14:56:23 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetStreamSource ( IWineD3DDevice * iface ,
UINT StreamNumber , IWineD3DBuffer * * pStream , UINT * pOffset , UINT * pStride )
{
2004-11-23 14:52:46 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-09-02 13:17:17 +02:00
2007-04-09 01:55:16 +02:00
TRACE ( " (%p) : StreamNo: %u, Stream (%p), Offset %u, Stride %u \n " , This , StreamNumber ,
This - > stateBlock - > streamSource [ StreamNumber ] ,
This - > stateBlock - > streamOffset [ StreamNumber ] ,
This - > stateBlock - > streamStride [ StreamNumber ] ) ;
2004-11-23 14:52:46 +01:00
2005-09-02 13:17:17 +02:00
if ( StreamNumber > = MAX_STREAMS ) {
WARN ( " Stream out of range %d \n " , StreamNumber ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-09-02 13:17:17 +02:00
}
2005-07-05 16:05:18 +02:00
* pStream = This - > stateBlock - > streamSource [ StreamNumber ] ;
* pStride = This - > stateBlock - > streamStride [ StreamNumber ] ;
2006-07-31 15:36:11 +02:00
if ( pOffset ) {
* pOffset = This - > stateBlock - > streamOffset [ StreamNumber ] ;
}
2005-09-02 13:17:17 +02:00
2006-12-24 10:00:05 +01:00
if ( * pStream ! = NULL ) {
2009-03-06 14:56:23 +01:00
IWineD3DBuffer_AddRef ( * pStream ) ; /* We have created a new reference to the VB */
2005-09-02 13:17:17 +02:00
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-23 14:52:46 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSourceFreq ( IWineD3DDevice * iface , UINT StreamNumber , UINT Divider ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-02-14 17:56:29 +01:00
UINT oldFlags = This - > updateStateBlock - > streamFlags [ StreamNumber ] ;
UINT oldFreq = This - > updateStateBlock - > streamFreq [ StreamNumber ] ;
2005-07-13 16:15:54 +02:00
2008-04-06 18:50:02 +02:00
/* Verify input at least in d3d9 this is invalid*/
if ( ( Divider & WINED3DSTREAMSOURCE_INSTANCEDATA ) & & ( Divider & WINED3DSTREAMSOURCE_INDEXEDDATA ) ) {
WARN ( " INSTANCEDATA and INDEXEDDATA were set, returning D3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
if ( ( Divider & WINED3DSTREAMSOURCE_INSTANCEDATA ) & & StreamNumber = = 0 ) {
WARN ( " INSTANCEDATA used on stream 0, returning D3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
if ( Divider = = 0 ) {
WARN ( " Divider is 0, returning D3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
2005-09-02 13:17:17 +02:00
TRACE ( " (%p) StreamNumber(%d), Divider(%d) \n " , This , StreamNumber , Divider ) ;
2006-10-31 09:19:13 +01:00
This - > updateStateBlock - > streamFlags [ StreamNumber ] = Divider & ( WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA ) ;
2005-09-02 13:17:17 +02:00
2008-12-31 16:57:11 +01:00
This - > updateStateBlock - > changed . streamFreq | = 1 < < StreamNumber ;
2005-09-02 13:17:17 +02:00
This - > updateStateBlock - > streamFreq [ StreamNumber ] = Divider & 0x7FFFFF ;
2007-02-14 17:56:29 +01:00
if ( This - > updateStateBlock - > streamFreq [ StreamNumber ] ! = oldFreq | |
This - > updateStateBlock - > streamFlags [ StreamNumber ] ! = oldFlags ) {
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_STREAMSRC ) ;
2005-09-02 13:17:17 +02:00
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-07-13 16:15:54 +02:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetStreamSourceFreq ( IWineD3DDevice * iface , UINT StreamNumber , UINT * Divider ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
2005-09-02 13:17:17 +02:00
TRACE ( " (%p) StreamNumber(%d), Divider(%p) \n " , This , StreamNumber , Divider ) ;
* Divider = This - > updateStateBlock - > streamFreq [ StreamNumber ] | This - > updateStateBlock - > streamFlags [ StreamNumber ] ;
TRACE ( " (%p) : returning %d \n " , This , * Divider ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2004-11-28 16:04:41 +01:00
/*****
2005-07-11 12:59:41 +02:00
* Get / Set & Multiply Transform
2004-11-28 16:04:41 +01:00
* * * * */
2006-10-12 08:21:39 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetTransform ( IWineD3DDevice * iface , WINED3DTRANSFORMSTATETYPE d3dts , CONST WINED3DMATRIX * lpmatrix ) {
2004-11-28 16:04:41 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
/* Most of this routine, comments included copied from ddraw tree initially: */
2006-07-24 04:54:30 +02:00
TRACE ( " (%p) : Transform State=%s \n " , This , debug_d3dtstype ( d3dts ) ) ;
2004-11-28 16:04:41 +01:00
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2009-01-05 10:10:16 +01:00
This - > updateStateBlock - > changed . transform [ d3dts > > 5 ] | = 1 < < ( d3dts & 0x1f ) ;
2008-03-20 23:25:13 +01:00
This - > updateStateBlock - > transforms [ d3dts ] = * lpmatrix ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-28 16:04:41 +01:00
}
/*
* If the new matrix is the same as the current one ,
* we cut off any further processing . this seems to be a reasonable
* optimization because as was noticed , some apps ( warcraft3 for example )
* tend towards setting the same matrix repeatedly for some reason .
*
* From here on we assume that the new matrix is different , wherever it matters .
*/
2006-10-12 08:21:39 +02:00
if ( ! memcmp ( & This - > stateBlock - > transforms [ d3dts ] . u . m [ 0 ] [ 0 ] , lpmatrix , sizeof ( WINED3DMATRIX ) ) ) {
2004-11-28 16:04:41 +01:00
TRACE ( " The app is setting the same matrix over again \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-28 16:04:41 +01:00
} else {
conv_mat ( lpmatrix , & This - > stateBlock - > transforms [ d3dts ] . u . m [ 0 ] [ 0 ] ) ;
}
/*
ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
where ViewMat = Camera space , WorldMat = world space .
In OpenGL , camera and world space is combined into GL_MODELVIEW
2005-07-13 16:15:54 +02:00
matrix . The Projection matrix stay projection matrix .
2004-11-28 16:04:41 +01:00
*/
/* Capture the times we can just ignore the change for now */
2008-01-09 20:37:05 +01:00
if ( d3dts = = WINED3DTS_VIEW ) { /* handle the VIEW matrix */
2005-07-13 16:15:54 +02:00
This - > view_ident = ! memcmp ( lpmatrix , identity , 16 * sizeof ( float ) ) ;
2007-01-02 00:48:58 +01:00
/* Handled by the state manager */
2004-11-28 16:04:41 +01:00
}
2007-01-02 00:48:58 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TRANSFORM ( d3dts ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-28 16:04:41 +01:00
}
2006-10-12 08:21:39 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetTransform ( IWineD3DDevice * iface , WINED3DTRANSFORMSTATETYPE State , WINED3DMATRIX * pMatrix ) {
2004-11-28 16:04:41 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-07-24 04:54:30 +02:00
TRACE ( " (%p) : for Transform State %s \n " , This , debug_d3dtstype ( State ) ) ;
2008-03-20 23:25:13 +01:00
* pMatrix = This - > stateBlock - > transforms [ State ] ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-28 16:04:41 +01:00
}
2006-10-12 08:21:39 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_MultiplyTransform ( IWineD3DDevice * iface , WINED3DTRANSFORMSTATETYPE State , CONST WINED3DMATRIX * pMatrix ) {
2008-11-26 16:14:39 +01:00
const WINED3DMATRIX * mat = NULL ;
2006-10-12 08:21:39 +02:00
WINED3DMATRIX temp ;
2004-11-29 18:53:42 +01:00
2004-12-20 20:27:06 +01:00
/* Note: Using 'updateStateBlock' rather than 'stateblock' in the code
* below means it will be recorded in a state block change , but it
2005-07-13 16:15:54 +02:00
* works regardless where it is recorded .
2004-12-20 20:27:06 +01:00
* If this is found to be wrong , change to StateBlock .
*/
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-07-24 04:54:30 +02:00
TRACE ( " (%p) : For state %s \n " , This , debug_d3dtstype ( State ) ) ;
2004-11-29 18:53:42 +01:00
2008-12-31 16:57:10 +01:00
if ( State < = HIGHEST_TRANSFORMSTATE )
2004-11-29 18:53:42 +01:00
{
mat = & This - > updateStateBlock - > transforms [ State ] ;
} else {
FIXME ( " Unhandled transform state!! \n " ) ;
}
2008-01-23 22:39:56 +01:00
multiply_matrix ( & temp , mat , pMatrix ) ;
2004-11-29 18:53:42 +01:00
/* Apply change via set transform - will reapply to eg. lights this way */
2005-08-22 11:13:49 +02:00
return IWineD3DDeviceImpl_SetTransform ( iface , State , & temp ) ;
2004-11-29 18:53:42 +01:00
}
/*****
* Get / Set Light
* * * * */
/* Note lights are real special cases. Although the device caps state only eg. 8 are supported,
2004-12-20 20:27:06 +01:00
you can reference any indexes you want as long as that number max are enabled at any
2007-02-19 15:24:26 +01:00
one point in time ! Therefore since the indexes can be anything , we need a hashmap of them .
However , this causes stateblock problems . When capturing the state block , I duplicate the hashmap ,
2004-11-29 18:53:42 +01:00
but when recording , just build a chain pretty much of commands to be replayed . */
2005-07-13 16:15:54 +02:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetLight ( IWineD3DDevice * iface , DWORD Index , CONST WINED3DLIGHT * pLight ) {
2004-11-29 18:53:42 +01:00
float rho ;
2009-10-14 10:55:16 +02:00
struct wined3d_light_info * object = NULL ;
2007-02-14 17:46:54 +01:00
UINT Hi = LIGHTMAP_HASHFUNC ( Index ) ;
struct list * e ;
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-02-14 17:46:54 +01:00
TRACE ( " (%p) : Idx(%d), pLight(%p). Hash index is %d \n " , This , Index , pLight , Hi ) ;
2004-11-29 18:53:42 +01:00
2007-02-20 22:43:13 +01:00
/* Check the parameter range. Need for speed most wanted sets junk lights which confuse
* the gl driver .
*/
if ( ! pLight ) {
WARN ( " Light pointer = NULL, returning WINED3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
switch ( pLight - > Type ) {
case WINED3DLIGHT_POINT :
case WINED3DLIGHT_SPOT :
case WINED3DLIGHT_PARALLELPOINT :
case WINED3DLIGHT_GLSPOT :
/* Incorrect attenuation values can cause the gl driver to crash. Happens with Need for speed
* most wanted
*/
2009-07-07 11:08:01 +02:00
if ( pLight - > Attenuation0 < 0.0f | | pLight - > Attenuation1 < 0.0f | | pLight - > Attenuation2 < 0.0f )
{
2007-02-20 22:43:13 +01:00
WARN ( " Attenuation is negative, returning WINED3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
break ;
case WINED3DLIGHT_DIRECTIONAL :
/* Ignores attenuation */
break ;
default :
WARN ( " Light type out of range, returning WINED3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
2009-10-14 10:55:16 +02:00
LIST_FOR_EACH ( e , & This - > updateStateBlock - > lightMap [ Hi ] )
{
object = LIST_ENTRY ( e , struct wined3d_light_info , entry ) ;
2007-02-14 17:46:54 +01:00
if ( object - > OriginalIndex = = Index ) break ;
object = NULL ;
2004-11-29 18:53:42 +01:00
}
2007-02-14 17:46:54 +01:00
if ( ! object ) {
TRACE ( " Adding new light \n " ) ;
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object ) {
ERR ( " Out of memory error when allocating a light \n " ) ;
return E_OUTOFMEMORY ;
2004-11-29 18:53:42 +01:00
}
2007-02-14 17:46:54 +01:00
list_add_head ( & This - > updateStateBlock - > lightMap [ Hi ] , & object - > entry ) ;
2004-11-29 18:53:42 +01:00
object - > glIndex = - 1 ;
2007-02-14 17:46:54 +01:00
object - > OriginalIndex = Index ;
2004-11-29 18:53:42 +01:00
}
2005-11-23 20:14:43 +01:00
/* Initialize the object */
2006-10-01 05:20:10 +02:00
TRACE ( " Light %d setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f) \n " , Index , pLight - > Type ,
2004-11-29 18:53:42 +01:00
pLight - > Diffuse . r , pLight - > Diffuse . g , pLight - > Diffuse . b , pLight - > Diffuse . a ,
pLight - > Specular . r , pLight - > Specular . g , pLight - > Specular . b , pLight - > Specular . a ,
pLight - > Ambient . r , pLight - > Ambient . g , pLight - > Ambient . b , pLight - > Ambient . a ) ;
TRACE ( " ... Pos(%f,%f,%f), Dirn(%f,%f,%f) \n " , pLight - > Position . x , pLight - > Position . y , pLight - > Position . z ,
pLight - > Direction . x , pLight - > Direction . y , pLight - > Direction . z ) ;
TRACE ( " ... Range(%f), Falloff(%f), Theta(%f), Phi(%f) \n " , pLight - > Range , pLight - > Falloff , pLight - > Theta , pLight - > Phi ) ;
/* Save away the information */
2008-03-20 23:25:13 +01:00
object - > OriginalParms = * pLight ;
2004-11-29 18:53:42 +01:00
switch ( pLight - > Type ) {
2006-10-11 03:55:47 +02:00
case WINED3DLIGHT_POINT :
2004-11-29 18:53:42 +01:00
/* Position */
object - > lightPosn [ 0 ] = pLight - > Position . x ;
object - > lightPosn [ 1 ] = pLight - > Position . y ;
object - > lightPosn [ 2 ] = pLight - > Position . z ;
object - > lightPosn [ 3 ] = 1.0f ;
object - > cutoff = 180.0f ;
/* FIXME: Range */
break ;
2006-10-11 03:55:47 +02:00
case WINED3DLIGHT_DIRECTIONAL :
2004-11-29 18:53:42 +01:00
/* Direction */
object - > lightPosn [ 0 ] = - pLight - > Direction . x ;
object - > lightPosn [ 1 ] = - pLight - > Direction . y ;
object - > lightPosn [ 2 ] = - pLight - > Direction . z ;
2009-07-07 11:08:01 +02:00
object - > lightPosn [ 3 ] = 0.0f ;
2004-11-29 18:53:42 +01:00
object - > exponent = 0.0f ;
object - > cutoff = 180.0f ;
break ;
2006-10-11 03:55:47 +02:00
case WINED3DLIGHT_SPOT :
2004-11-29 18:53:42 +01:00
/* Position */
object - > lightPosn [ 0 ] = pLight - > Position . x ;
object - > lightPosn [ 1 ] = pLight - > Position . y ;
object - > lightPosn [ 2 ] = pLight - > Position . z ;
2009-07-07 11:08:01 +02:00
object - > lightPosn [ 3 ] = 1.0f ;
2004-11-29 18:53:42 +01:00
/* Direction */
object - > lightDirn [ 0 ] = pLight - > Direction . x ;
object - > lightDirn [ 1 ] = pLight - > Direction . y ;
object - > lightDirn [ 2 ] = pLight - > Direction . z ;
2009-07-07 11:08:01 +02:00
object - > lightDirn [ 3 ] = 1.0f ;
2004-11-29 18:53:42 +01:00
/*
* opengl - ish and d3d - ish spot lights use too different models for the
* light " intensity " as a function of the angle towards the main light direction ,
* so we only can approximate very roughly .
* however spot lights are rather rarely used in games ( if ever used at all ) .
* furthermore if still used , probably nobody pays attention to such details .
*/
if ( pLight - > Falloff = = 0 ) {
2007-08-20 22:10:36 +02:00
/* Falloff = 0 is easy, because d3d's and opengl's spot light equations have the
* falloff resp . exponent parameter as an exponent , so the spot light lighting
* will always be 1.0 for both of them , and we don ' t have to care for the
* rest of the rather complex calculation
*/
2009-07-07 11:08:01 +02:00
object - > exponent = 0.0f ;
2004-11-29 18:53:42 +01:00
} else {
rho = pLight - > Theta + ( pLight - > Phi - pLight - > Theta ) / ( 2 * pLight - > Falloff ) ;
2009-07-07 11:08:01 +02:00
if ( rho < 0.0001f ) rho = 0.0001f ;
object - > exponent = - 0.3f / logf ( cosf ( rho / 2 ) ) ;
2004-11-29 18:53:42 +01:00
}
2009-07-07 11:08:01 +02:00
if ( object - > exponent > 128.0f )
{
object - > exponent = 128.0f ;
2009-01-09 10:23:43 +01:00
}
2004-11-29 18:53:42 +01:00
object - > cutoff = pLight - > Phi * 90 / M_PI ;
/* FIXME: Range */
break ;
default :
FIXME ( " Unrecognized light type %d \n " , pLight - > Type ) ;
}
/* Update the live definitions if the light is currently assigned a glIndex */
2007-02-14 17:46:54 +01:00
if ( object - > glIndex ! = - 1 & & ! This - > isRecordingState ) {
2007-02-14 17:48:52 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_ACTIVELIGHT ( object - > glIndex ) ) ;
2004-11-29 18:53:42 +01:00
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2009-10-14 10:55:16 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetLight ( IWineD3DDevice * iface , DWORD Index , WINED3DLIGHT * pLight )
{
struct wined3d_light_info * lightInfo = NULL ;
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-02-14 17:46:54 +01:00
DWORD Hi = LIGHTMAP_HASHFUNC ( Index ) ;
struct list * e ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Idx(%d), pLight(%p) \n " , This , Index , pLight ) ;
2005-07-13 16:15:54 +02:00
2009-10-14 10:55:16 +02:00
LIST_FOR_EACH ( e , & This - > stateBlock - > lightMap [ Hi ] )
{
lightInfo = LIST_ENTRY ( e , struct wined3d_light_info , entry ) ;
2007-02-14 17:46:54 +01:00
if ( lightInfo - > OriginalIndex = = Index ) break ;
lightInfo = NULL ;
}
2004-11-29 18:53:42 +01:00
if ( lightInfo = = NULL ) {
TRACE ( " Light information requested but light not defined \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-11-29 18:53:42 +01:00
}
2008-03-20 23:25:13 +01:00
* pLight = lightInfo - > OriginalParms ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
/*****
2005-07-13 16:15:54 +02:00
* Get / Set Light Enable
2004-11-29 18:53:42 +01:00
* ( Note for consistency , renamed d3dx function by adding the ' set ' prefix )
* * * * */
2009-10-14 10:55:16 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetLightEnable ( IWineD3DDevice * iface , DWORD Index , BOOL Enable )
{
struct wined3d_light_info * lightInfo = NULL ;
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-02-14 17:46:54 +01:00
UINT Hi = LIGHTMAP_HASHFUNC ( Index ) ;
struct list * e ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Idx(%d), enable? %d \n " , This , Index , Enable ) ;
2004-11-29 18:53:42 +01:00
2009-10-14 10:55:16 +02:00
LIST_FOR_EACH ( e , & This - > updateStateBlock - > lightMap [ Hi ] )
{
lightInfo = LIST_ENTRY ( e , struct wined3d_light_info , entry ) ;
2007-02-14 17:46:54 +01:00
if ( lightInfo - > OriginalIndex = = Index ) break ;
lightInfo = NULL ;
2004-11-29 18:53:42 +01:00
}
2007-02-14 17:46:54 +01:00
TRACE ( " Found light: %p \n " , lightInfo ) ;
2004-11-29 18:53:42 +01:00
/* Special case - enabling an undefined light creates one with a strict set of parms! */
if ( lightInfo = = NULL ) {
2006-06-07 05:37:05 +02:00
2005-07-13 16:15:54 +02:00
TRACE ( " Light enabled requested but light not defined, so defining one! \n " ) ;
2006-06-07 05:37:05 +02:00
IWineD3DDeviceImpl_SetLight ( iface , Index , & WINED3D_default_light ) ;
2004-11-29 18:53:42 +01:00
/* Search for it again! Should be fairly quick as near head of list */
2009-10-14 10:55:16 +02:00
LIST_FOR_EACH ( e , & This - > updateStateBlock - > lightMap [ Hi ] )
{
lightInfo = LIST_ENTRY ( e , struct wined3d_light_info , entry ) ;
2007-02-14 17:46:54 +01:00
if ( lightInfo - > OriginalIndex = = Index ) break ;
lightInfo = NULL ;
}
2004-11-29 18:53:42 +01:00
if ( lightInfo = = NULL ) {
FIXME ( " Adding default lights has failed dismally \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-11-29 18:53:42 +01:00
}
}
2007-02-14 17:46:54 +01:00
if ( ! Enable ) {
if ( lightInfo - > glIndex ! = - 1 ) {
if ( ! This - > isRecordingState ) {
2007-02-14 17:48:52 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_ACTIVELIGHT ( lightInfo - > glIndex ) ) ;
2007-02-14 17:46:54 +01:00
}
2004-11-29 18:53:42 +01:00
2008-10-03 08:55:41 +02:00
This - > updateStateBlock - > activeLights [ lightInfo - > glIndex ] = NULL ;
2007-02-14 17:46:54 +01:00
lightInfo - > glIndex = - 1 ;
2004-11-29 18:53:42 +01:00
} else {
2007-02-14 17:46:54 +01:00
TRACE ( " Light already disabled, nothing to do \n " ) ;
2004-11-29 18:53:42 +01:00
}
2007-11-29 13:22:47 +01:00
lightInfo - > enabled = FALSE ;
2004-11-29 18:53:42 +01:00
} else {
2007-11-29 13:22:47 +01:00
lightInfo - > enabled = TRUE ;
2007-02-14 17:46:54 +01:00
if ( lightInfo - > glIndex ! = - 1 ) {
2004-11-29 18:53:42 +01:00
/* nop */
TRACE ( " Nothing to do as light was enabled \n " ) ;
} else {
2007-02-14 17:46:54 +01:00
int i ;
/* Find a free gl light */
for ( i = 0 ; i < This - > maxConcurrentLights ; i + + ) {
2008-10-03 08:55:41 +02:00
if ( This - > updateStateBlock - > activeLights [ i ] = = NULL ) {
This - > updateStateBlock - > activeLights [ i ] = lightInfo ;
2007-02-14 17:46:54 +01:00
lightInfo - > glIndex = i ;
break ;
2004-11-29 18:53:42 +01:00
}
}
2007-02-14 17:46:54 +01:00
if ( lightInfo - > glIndex = = - 1 ) {
2007-11-29 13:22:47 +01:00
/* Our tests show that Windows returns D3D_OK in this situation, even with
* D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE devices . This
* is consistent among ddraw , d3d8 and d3d9 . GetLightEnable returns TRUE
* as well for those lights .
*
* TODO : Test how this affects rendering
*/
2008-12-29 16:31:22 +01:00
WARN ( " Too many concurrently active lights \n " ) ;
2007-11-29 13:22:47 +01:00
return WINED3D_OK ;
2007-02-14 17:46:54 +01:00
}
2004-11-29 18:53:42 +01:00
2007-02-14 17:46:54 +01:00
/* i == lightInfo->glIndex */
if ( ! This - > isRecordingState ) {
2007-02-14 17:48:52 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_ACTIVELIGHT ( i ) ) ;
2004-11-29 18:53:42 +01:00
}
}
}
2007-02-14 17:46:54 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2009-10-14 10:55:16 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetLightEnable ( IWineD3DDevice * iface , DWORD Index , BOOL * pEnable )
{
struct wined3d_light_info * lightInfo = NULL ;
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-02-14 17:46:54 +01:00
struct list * e ;
UINT Hi = LIGHTMAP_HASHFUNC ( Index ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : for idx(%d) \n " , This , Index ) ;
2005-07-13 16:15:54 +02:00
2009-10-14 10:55:16 +02:00
LIST_FOR_EACH ( e , & This - > stateBlock - > lightMap [ Hi ] )
{
lightInfo = LIST_ENTRY ( e , struct wined3d_light_info , entry ) ;
2007-02-14 17:46:54 +01:00
if ( lightInfo - > OriginalIndex = = Index ) break ;
lightInfo = NULL ;
}
2004-11-29 18:53:42 +01:00
if ( lightInfo = = NULL ) {
TRACE ( " Light enabled state requested but light not defined \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-11-29 18:53:42 +01:00
}
2007-02-14 17:46:54 +01:00
/* true is 128 according to SetLightEnable */
2007-11-29 13:22:47 +01:00
* pEnable = lightInfo - > enabled ? 128 : 0 ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
/*****
* Get / Set Clip Planes
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetClipPlane ( IWineD3DDevice * iface , DWORD Index , CONST float * pPlane ) {
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : for idx %d, %p \n " , This , Index , pPlane ) ;
2004-11-29 18:53:42 +01:00
/* Validate Index */
2009-10-29 10:37:10 +01:00
if ( Index > = This - > adapter - > gl_info . limits . clipplanes )
2009-10-22 10:09:54 +02:00
{
2004-11-29 18:53:42 +01:00
TRACE ( " Application has requested clipplane this device doesn't support \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-11-29 18:53:42 +01:00
}
2008-12-31 16:57:11 +01:00
This - > updateStateBlock - > changed . clipplane | = 1 < < Index ;
2007-02-28 14:36:36 +01:00
if ( This - > updateStateBlock - > clipplane [ Index ] [ 0 ] = = pPlane [ 0 ] & &
This - > updateStateBlock - > clipplane [ Index ] [ 1 ] = = pPlane [ 1 ] & &
This - > updateStateBlock - > clipplane [ Index ] [ 2 ] = = pPlane [ 2 ] & &
This - > updateStateBlock - > clipplane [ Index ] [ 3 ] = = pPlane [ 3 ] ) {
TRACE ( " Application is setting old values over, nothing to do \n " ) ;
return WINED3D_OK ;
}
2004-11-29 18:53:42 +01:00
This - > updateStateBlock - > clipplane [ Index ] [ 0 ] = pPlane [ 0 ] ;
This - > updateStateBlock - > clipplane [ Index ] [ 1 ] = pPlane [ 1 ] ;
This - > updateStateBlock - > clipplane [ Index ] [ 2 ] = pPlane [ 2 ] ;
This - > updateStateBlock - > clipplane [ Index ] [ 3 ] = pPlane [ 3 ] ;
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2007-02-28 14:36:36 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_CLIPPLANE ( Index ) ) ;
2004-11-29 18:53:42 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetClipPlane ( IWineD3DDevice * iface , DWORD Index , float * pPlane ) {
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : for idx %d \n " , This , Index ) ;
2004-11-29 18:53:42 +01:00
/* Validate Index */
2009-10-29 10:37:10 +01:00
if ( Index > = This - > adapter - > gl_info . limits . clipplanes )
2009-10-22 10:09:54 +02:00
{
2004-11-29 18:53:42 +01:00
TRACE ( " Application has requested clipplane this device doesn't support \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-11-29 18:53:42 +01:00
}
pPlane [ 0 ] = This - > stateBlock - > clipplane [ Index ] [ 0 ] ;
pPlane [ 1 ] = This - > stateBlock - > clipplane [ Index ] [ 1 ] ;
pPlane [ 2 ] = This - > stateBlock - > clipplane [ Index ] [ 2 ] ;
pPlane [ 3 ] = This - > stateBlock - > clipplane [ Index ] [ 3 ] ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
/*****
* Get / Set Clip Plane Status
* WARNING : This code relies on the fact that D3DCLIPSTATUS8 = = D3DCLIPSTATUS9
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetClipStatus ( IWineD3DDevice * iface , CONST WINED3DCLIPSTATUS * pClipStatus ) {
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
FIXME ( " (%p) : stub \n " , This ) ;
if ( NULL = = pClipStatus ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-11-29 18:53:42 +01:00
}
This - > updateStateBlock - > clip_status . ClipUnion = pClipStatus - > ClipUnion ;
This - > updateStateBlock - > clip_status . ClipIntersection = pClipStatus - > ClipIntersection ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetClipStatus ( IWineD3DDevice * iface , WINED3DCLIPSTATUS * pClipStatus ) {
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
FIXME ( " (%p) : stub \n " , This ) ;
2004-11-29 18:53:42 +01:00
if ( NULL = = pClipStatus ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-11-29 18:53:42 +01:00
}
pClipStatus - > ClipUnion = This - > updateStateBlock - > clip_status . ClipUnion ;
pClipStatus - > ClipIntersection = This - > updateStateBlock - > clip_status . ClipIntersection ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
/*****
* Get / Set Material
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetMaterial ( IWineD3DDevice * iface , CONST WINED3DMATERIAL * pMaterial ) {
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
This - > updateStateBlock - > changed . material = TRUE ;
2008-03-20 23:25:13 +01:00
This - > updateStateBlock - > material = * pMaterial ;
2004-11-29 18:53:42 +01:00
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2007-06-15 21:33:54 +02:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_MATERIAL ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetMaterial ( IWineD3DDevice * iface , WINED3DMATERIAL * pMaterial ) {
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2008-03-20 23:25:13 +01:00
* pMaterial = This - > updateStateBlock - > material ;
2005-08-22 11:13:49 +02:00
TRACE ( " (%p) : Diffuse (%f,%f,%f,%f) \n " , This , pMaterial - > Diffuse . r , pMaterial - > Diffuse . g ,
pMaterial - > Diffuse . b , pMaterial - > Diffuse . a ) ;
TRACE ( " (%p) : Ambient (%f,%f,%f,%f) \n " , This , pMaterial - > Ambient . r , pMaterial - > Ambient . g ,
pMaterial - > Ambient . b , pMaterial - > Ambient . a ) ;
TRACE ( " (%p) : Specular (%f,%f,%f,%f) \n " , This , pMaterial - > Specular . r , pMaterial - > Specular . g ,
pMaterial - > Specular . b , pMaterial - > Specular . a ) ;
TRACE ( " (%p) : Emissive (%f,%f,%f,%f) \n " , This , pMaterial - > Emissive . r , pMaterial - > Emissive . g ,
pMaterial - > Emissive . b , pMaterial - > Emissive . a ) ;
2004-11-29 18:53:42 +01:00
TRACE ( " (%p) : Power (%f) \n " , This , pMaterial - > Power ) ;
2005-08-22 11:13:49 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-29 18:53:42 +01:00
}
2004-12-09 12:42:34 +01:00
/*****
* Get / Set Indices
* * * * */
2009-09-25 13:31:45 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetIndexBuffer ( IWineD3DDevice * iface ,
IWineD3DBuffer * pIndexData , WINED3DFORMAT fmt )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-04-06 16:46:12 +02:00
IWineD3DBuffer * oldIdxs ;
2004-12-09 12:42:34 +01:00
2007-06-05 18:52:21 +02:00
TRACE ( " (%p) : Setting to %p \n " , This , pIndexData ) ;
2004-12-09 12:42:34 +01:00
oldIdxs = This - > updateStateBlock - > pIndexData ;
This - > updateStateBlock - > changed . indices = TRUE ;
This - > updateStateBlock - > pIndexData = pIndexData ;
2009-04-09 10:50:31 +02:00
This - > updateStateBlock - > IndexFmt = fmt ;
2004-12-09 12:42:34 +01:00
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2009-04-06 16:46:12 +02:00
if ( pIndexData ) IWineD3DBuffer_AddRef ( pIndexData ) ;
if ( oldIdxs ) IWineD3DBuffer_Release ( oldIdxs ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2007-02-19 15:25:32 +01:00
if ( oldIdxs ! = pIndexData ) {
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_INDEXBUFFER ) ;
2009-04-06 13:38:56 +02:00
if ( pIndexData ) {
InterlockedIncrement ( & ( ( struct wined3d_buffer * ) pIndexData ) - > bind_count ) ;
2009-04-06 16:46:12 +02:00
IWineD3DBuffer_AddRef ( pIndexData ) ;
2009-04-06 13:38:56 +02:00
}
if ( oldIdxs ) {
InterlockedDecrement ( & ( ( struct wined3d_buffer * ) oldIdxs ) - > bind_count ) ;
2009-04-06 16:46:12 +02:00
IWineD3DBuffer_Release ( oldIdxs ) ;
2009-04-06 13:38:56 +02:00
}
2007-02-19 15:25:32 +01:00
}
2009-04-06 13:38:56 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2009-09-25 13:31:46 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetIndexBuffer ( IWineD3DDevice * iface , IWineD3DBuffer * * ppIndexData )
{
2004-12-09 12:42:34 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
* ppIndexData = This - > stateBlock - > pIndexData ;
2005-07-13 16:15:54 +02:00
2006-11-30 13:33:18 +01:00
/* up ref count on ppindexdata */
2005-08-22 11:13:49 +02:00
if ( * ppIndexData ) {
2009-04-06 16:46:12 +02:00
IWineD3DBuffer_AddRef ( * ppIndexData ) ;
2007-06-06 18:40:09 +02:00
TRACE ( " (%p) index data set to %p \n " , This , ppIndexData ) ;
2005-08-22 11:13:49 +02:00
} else {
TRACE ( " (%p) No index data set \n " , This ) ;
}
2007-06-06 18:40:09 +02:00
TRACE ( " Returning %p \n " , * ppIndexData ) ;
2004-12-09 12:42:34 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2007-01-02 21:07:39 +01:00
/* Method to offer d3d9 a simple way to set the base vertex index without messing with the index buffer */
2007-08-25 00:09:33 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetBaseVertexIndex ( IWineD3DDevice * iface , INT BaseIndex ) {
2007-01-02 21:07:39 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " (%p)->(%d) \n " , This , BaseIndex ) ;
if ( This - > updateStateBlock - > baseVertexIndex = = BaseIndex ) {
TRACE ( " Application is setting the old value over, nothing to do \n " ) ;
return WINED3D_OK ;
}
This - > updateStateBlock - > baseVertexIndex = BaseIndex ;
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
return WINED3D_OK ;
}
2007-06-05 18:52:21 +02:00
/* The base vertex index affects the stream sources */
2007-01-02 21:07:39 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_STREAMSRC ) ;
return WINED3D_OK ;
}
2007-08-25 00:09:33 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetBaseVertexIndex ( IWineD3DDevice * iface , INT * base_index ) {
2007-06-06 18:40:02 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " (%p) : base_index %p \n " , This , base_index ) ;
* base_index = This - > stateBlock - > baseVertexIndex ;
TRACE ( " Returning %u \n " , * base_index ) ;
return WINED3D_OK ;
}
2004-12-09 12:42:34 +01:00
/*****
* Get / Set Viewports
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetViewport ( IWineD3DDevice * iface , CONST WINED3DVIEWPORT * pViewport ) {
2004-12-09 12:42:34 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " (%p) \n " , This ) ;
This - > updateStateBlock - > changed . viewport = TRUE ;
2008-03-20 23:25:13 +01:00
This - > updateStateBlock - > viewport = * pViewport ;
2004-12-09 12:42:34 +01:00
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : x=%d, y=%d, wid=%d, hei=%d, minz=%f, maxz=%f \n " , This ,
2004-12-09 12:42:34 +01:00
pViewport - > X , pViewport - > Y , pViewport - > Width , pViewport - > Height , pViewport - > MinZ , pViewport - > MaxZ ) ;
2007-01-02 21:40:59 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VIEWPORT ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetViewport ( IWineD3DDevice * iface , WINED3DVIEWPORT * pViewport ) {
2004-12-09 12:42:34 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " (%p) \n " , This ) ;
2008-03-20 23:25:13 +01:00
* pViewport = This - > stateBlock - > viewport ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2004-12-13 14:35:38 +01:00
/*****
* Get / Set Render States
* TODO : Verify against dx9 definitions
* * * * */
2006-10-12 08:19:57 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState ( IWineD3DDevice * iface , WINED3DRENDERSTATETYPE State , DWORD Value ) {
2004-12-13 14:35:38 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-12-15 19:16:36 +01:00
DWORD oldValue = This - > stateBlock - > renderState [ State ] ;
2005-07-13 16:15:54 +02:00
2006-10-01 05:20:10 +02:00
TRACE ( " (%p)->state = %s(%d), value = %d \n " , This , debug_d3drenderstate ( State ) , State , Value ) ;
2006-12-15 19:16:36 +01:00
2009-01-05 10:10:16 +01:00
This - > updateStateBlock - > changed . renderState [ State > > 5 ] | = 1 < < ( State & 0x1f ) ;
2004-12-13 14:35:38 +01:00
This - > updateStateBlock - > renderState [ State ] = Value ;
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-13 14:35:38 +01:00
}
2006-12-15 19:16:36 +01:00
/* Compared here and not before the assignment to allow proper stateblock recording */
if ( Value = = oldValue ) {
TRACE ( " Application is setting the old value over, nothing to do \n " ) ;
} else {
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( State ) ) ;
}
2004-12-13 14:35:38 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-13 14:35:38 +01:00
}
2006-10-12 08:19:57 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderState ( IWineD3DDevice * iface , WINED3DRENDERSTATETYPE State , DWORD * pValue ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) for State %d = %d \n " , This , State , This - > stateBlock - > renderState [ State ] ) ;
2005-03-02 13:16:10 +01:00
* pValue = This - > stateBlock - > renderState [ State ] ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-08-01 12:58:31 +02:00
/*****
2005-08-03 13:00:28 +02:00
* Get / Set Sampler States
2005-08-01 12:58:31 +02:00
* TODO : Verify against dx9 definitions
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState ( IWineD3DDevice * iface , DWORD Sampler , WINED3DSAMPLERSTATETYPE Type , DWORD Value ) {
2005-08-01 12:58:31 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-06-25 22:45:57 +02:00
DWORD oldValue ;
TRACE ( " (%p) : Sampler %#x, Type %s (%#x), Value %#x \n " ,
This , Sampler , debug_d3dsamplerstate ( Type ) , Type , Value ) ;
if ( Sampler > = WINED3DVERTEXTEXTURESAMPLER0 & & Sampler < = WINED3DVERTEXTEXTURESAMPLER3 ) {
Sampler - = ( WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS ) ;
}
2006-12-19 23:17:17 +01:00
2008-01-15 08:06:37 +01:00
if ( Sampler > = sizeof ( This - > stateBlock - > samplerState ) / sizeof ( This - > stateBlock - > samplerState [ 0 ] ) ) {
2008-01-24 14:03:10 +01:00
ERR ( " Current Sampler overflows sampleState0 array (sampler %d) \n " , Sampler ) ;
2008-01-15 08:06:37 +01:00
return WINED3D_OK ; /* Windows accepts overflowing this array ... we do not. */
}
2005-08-01 12:58:31 +02:00
/**
* SetSampler is designed to allow for more than the standard up to 8 textures
* and Geforce has stopped supporting more than 6 standard textures in openGL .
* So I have to use ARB for Gforce . ( maybe if the sampler > 4 then use ARB ? )
*
* http : //developer.nvidia.com/object/General_FAQ.html#t6
*
* There are two new settings for GForce
* the sampler one :
* GL_MAX_TEXTURE_IMAGE_UNITS_ARB
* and the texture one :
* GL_MAX_TEXTURE_COORDS_ARB .
* Ok GForce say it ' s ok to use glTexParameter / glGetTexParameter ( . . . ) .
* * * * * * * * * * * * * * * * * */
2006-06-09 23:47:16 +02:00
2007-06-25 22:45:57 +02:00
oldValue = This - > stateBlock - > samplerState [ Sampler ] [ Type ] ;
2005-08-01 12:58:31 +02:00
This - > updateStateBlock - > samplerState [ Sampler ] [ Type ] = Value ;
2009-01-05 10:10:16 +01:00
This - > updateStateBlock - > changed . samplerState [ Sampler ] | = 1 < < Type ;
2005-08-01 12:58:31 +02:00
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-08-01 12:58:31 +02:00
}
2006-12-19 23:17:17 +01:00
if ( oldValue = = Value ) {
TRACE ( " Application is setting the old value over, nothing to do \n " ) ;
return WINED3D_OK ;
}
2006-12-19 23:26:39 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( Sampler ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetSamplerState ( IWineD3DDevice * iface , DWORD Sampler , WINED3DSAMPLERSTATETYPE Type , DWORD * Value ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-06-25 22:45:57 +02:00
TRACE ( " (%p) : Sampler %#x, Type %s (%#x) \n " ,
This , Sampler , debug_d3dsamplerstate ( Type ) , Type ) ;
if ( Sampler > = WINED3DVERTEXTEXTURESAMPLER0 & & Sampler < = WINED3DVERTEXTEXTURESAMPLER3 ) {
Sampler - = ( WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS ) ;
}
2008-01-15 08:06:37 +01:00
if ( Sampler > = sizeof ( This - > stateBlock - > samplerState ) / sizeof ( This - > stateBlock - > samplerState [ 0 ] ) ) {
2008-01-24 14:03:10 +01:00
ERR ( " Current Sampler overflows sampleState0 array (sampler %d) \n " , Sampler ) ;
2008-01-15 08:06:37 +01:00
return WINED3D_OK ; /* Windows accepts overflowing this array ... we do not. */
}
2006-10-29 01:55:55 +02:00
* Value = This - > stateBlock - > samplerState [ Sampler ] [ Type ] ;
2007-06-25 22:45:57 +02:00
TRACE ( " (%p) : Returning %#x \n " , This , * Value ) ;
2005-03-02 13:16:10 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetScissorRect ( IWineD3DDevice * iface , CONST RECT * pRect ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
2007-01-10 11:28:42 +01:00
This - > updateStateBlock - > changed . scissorRect = TRUE ;
2007-02-20 22:47:38 +01:00
if ( EqualRect ( & This - > updateStateBlock - > scissorRect , pRect ) ) {
2007-02-19 15:25:16 +01:00
TRACE ( " App is setting the old scissor rectangle over, nothing to do \n " ) ;
return WINED3D_OK ;
}
2007-02-20 22:47:38 +01:00
CopyRect ( & This - > updateStateBlock - > scissorRect , pRect ) ;
2007-01-10 11:28:42 +01:00
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
return WINED3D_OK ;
}
2007-02-19 15:25:16 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SCISSORRECT ) ;
2005-08-01 12:58:31 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetScissorRect ( IWineD3DDevice * iface , RECT * pRect ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2008-02-13 20:55:43 +01:00
* pRect = This - > updateStateBlock - > scissorRect ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p)Returning a Scissor Rect of %d:%d-%d:%d \n " , This , pRect - > left , pRect - > top , pRect - > right , pRect - > bottom ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexDeclaration ( IWineD3DDevice * iface , IWineD3DVertexDeclaration * pDecl ) {
2005-07-07 22:45:39 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-02-06 11:31:57 +01:00
IWineD3DVertexDeclaration * oldDecl = This - > updateStateBlock - > vertexDecl ;
2005-07-07 22:45:39 +02:00
2005-03-02 13:16:10 +01:00
TRACE ( " (%p) : pDecl=%p \n " , This , pDecl ) ;
2009-09-28 10:05:00 +02:00
if ( pDecl ) IWineD3DVertexDeclaration_AddRef ( pDecl ) ;
if ( oldDecl ) IWineD3DVertexDeclaration_Release ( oldDecl ) ;
2005-12-16 12:38:24 +01:00
This - > updateStateBlock - > vertexDecl = pDecl ;
This - > updateStateBlock - > changed . vertexDecl = TRUE ;
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2007-01-04 00:07:00 +01:00
return WINED3D_OK ;
} else if ( pDecl = = oldDecl ) {
/* Checked after the assignment to allow proper stateblock recording */
TRACE ( " Application is setting the old declaration over, nothing to do \n " ) ;
return WINED3D_OK ;
2005-12-16 12:38:24 +01:00
}
2007-01-02 00:35:07 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VDECL ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexDeclaration ( IWineD3DDevice * iface , IWineD3DVertexDeclaration * * ppDecl ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " (%p) : ppDecl=%p \n " , This , ppDecl ) ;
2005-07-13 16:15:54 +02:00
2005-12-14 10:50:27 +01:00
* ppDecl = This - > stateBlock - > vertexDecl ;
2005-03-02 13:16:10 +01:00
if ( NULL ! = * ppDecl ) IWineD3DVertexDeclaration_AddRef ( * ppDecl ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShader ( IWineD3DDevice * iface , IWineD3DVertexShader * pShader ) {
2005-12-15 10:25:47 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DVertexShader * oldShader = This - > updateStateBlock - > vertexShader ;
2005-07-13 16:15:54 +02:00
2005-12-15 10:25:47 +01:00
This - > updateStateBlock - > vertexShader = pShader ;
2005-03-02 13:16:10 +01:00
This - > updateStateBlock - > changed . vertexShader = TRUE ;
2005-07-13 16:15:54 +02:00
2005-08-17 13:34:03 +02:00
if ( This - > isRecordingState ) {
2007-08-20 18:56:10 +02:00
if ( pShader ) IWineD3DVertexShader_AddRef ( pShader ) ;
if ( oldShader ) IWineD3DVertexShader_Release ( oldShader ) ;
2005-08-17 13:34:03 +02:00
TRACE ( " Recording... not performing anything \n " ) ;
2007-01-04 00:07:45 +01:00
return WINED3D_OK ;
} else if ( oldShader = = pShader ) {
/* Checked here to allow proper stateblock recording */
TRACE ( " App is setting the old shader over, nothing to do \n " ) ;
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-12-13 11:11:01 +01:00
TRACE ( " (%p) : setting pShader(%p) \n " , This , pShader ) ;
2007-08-20 18:56:10 +02:00
if ( pShader ) IWineD3DVertexShader_AddRef ( pShader ) ;
if ( oldShader ) IWineD3DVertexShader_Release ( oldShader ) ;
2007-01-02 00:35:07 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VSHADER ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShader ( IWineD3DDevice * iface , IWineD3DVertexShader * * ppShader ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-08-22 11:13:49 +02:00
if ( NULL = = ppShader ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-08-22 11:13:49 +02:00
}
* ppShader = This - > stateBlock - > vertexShader ;
if ( NULL ! = * ppShader )
2005-03-02 13:16:10 +01:00
IWineD3DVertexShader_AddRef ( * ppShader ) ;
2005-08-22 11:13:49 +02:00
2005-03-02 13:16:10 +01:00
TRACE ( " (%p) : returning %p \n " , This , * ppShader ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantB (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
CONST BOOL * srcData ,
UINT count ) {
2005-03-02 13:16:10 +01:00
2006-06-06 08:46:59 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-25 10:12:27 +01:00
unsigned int i , cnt = min ( count , MAX_CONST_B - start ) ;
2005-09-21 12:19:29 +02:00
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, srcData %p, start %d, count %d) \n " ,
iface , srcData , start , count ) ;
2005-09-21 12:19:29 +02:00
2009-03-25 10:12:27 +01:00
if ( ! srcData | | start > = MAX_CONST_B ) return WINED3DERR_INVALIDCALL ;
2005-09-21 12:19:29 +02:00
2006-06-06 23:17:35 +02:00
memcpy ( & This - > updateStateBlock - > vertexShaderConstantB [ start ] , srcData , cnt * sizeof ( BOOL ) ) ;
2006-07-03 03:26:03 +02:00
for ( i = 0 ; i < cnt ; i + + )
2006-07-21 15:19:04 +02:00
TRACE ( " Set BOOL constant %u to %s \n " , start + i , srcData [ i ] ? " true " : " false " ) ;
2005-09-21 12:19:29 +02:00
2005-12-20 11:46:52 +01:00
for ( i = start ; i < cnt + start ; + + i ) {
2008-12-02 18:41:33 +01:00
This - > updateStateBlock - > changed . vertexShaderConstantsB | = ( 1 < < i ) ;
2005-08-17 12:27:01 +02:00
}
2005-09-21 12:19:29 +02:00
2008-12-17 17:07:25 +01:00
if ( ! This - > isRecordingState ) IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VERTEXSHADERCONSTANT ) ;
2007-01-06 18:17:27 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantB (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
BOOL * dstData ,
UINT count ) {
2005-09-21 12:19:29 +02:00
2006-06-06 08:46:59 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-07-19 06:06:07 +02:00
int cnt = min ( count , MAX_CONST_B - start ) ;
2005-09-21 12:19:29 +02:00
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, dstData %p, start %d, count %d) \n " ,
iface , dstData , start , count ) ;
2005-09-21 12:19:29 +02:00
2006-06-06 08:46:59 +02:00
if ( dstData = = NULL | | cnt < 0 )
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-09-21 12:19:29 +02:00
2006-07-21 05:02:29 +02:00
memcpy ( dstData , & This - > stateBlock - > vertexShaderConstantB [ start ] , cnt * sizeof ( BOOL ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantI (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
CONST int * srcData ,
UINT count ) {
2005-09-21 12:19:29 +02:00
2005-12-20 11:46:52 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-25 10:12:27 +01:00
unsigned int i , cnt = min ( count , MAX_CONST_I - start ) ;
2005-03-02 13:16:10 +01:00
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, srcData %p, start %d, count %d) \n " ,
iface , srcData , start , count ) ;
2009-03-25 10:12:27 +01:00
if ( ! srcData | | start > = MAX_CONST_I ) return WINED3DERR_INVALIDCALL ;
2006-06-06 08:46:59 +02:00
2006-06-06 23:17:35 +02:00
memcpy ( & This - > updateStateBlock - > vertexShaderConstantI [ start * 4 ] , srcData , cnt * sizeof ( int ) * 4 ) ;
2006-07-03 03:26:03 +02:00
for ( i = 0 ; i < cnt ; i + + )
2006-07-21 15:19:04 +02:00
TRACE ( " Set INT constant %u to { %d, %d, %d, %d } \n " , start + i ,
2006-07-03 03:26:03 +02:00
srcData [ i * 4 ] , srcData [ i * 4 + 1 ] , srcData [ i * 4 + 2 ] , srcData [ i * 4 + 3 ] ) ;
2006-06-06 08:46:59 +02:00
for ( i = start ; i < cnt + start ; + + i ) {
2008-12-02 18:41:33 +01:00
This - > updateStateBlock - > changed . vertexShaderConstantsI | = ( 1 < < i ) ;
2006-06-06 08:46:59 +02:00
}
2008-12-17 17:07:25 +01:00
if ( ! This - > isRecordingState ) IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VERTEXSHADERCONSTANT ) ;
2007-01-06 18:17:27 +01:00
2006-06-06 08:46:59 +02:00
return WINED3D_OK ;
2005-12-20 11:46:52 +01:00
}
2005-09-21 12:19:29 +02:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
int * dstData ,
UINT count ) {
2005-12-20 11:46:52 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-07-19 06:06:07 +02:00
int cnt = min ( count , MAX_CONST_I - start ) ;
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, dstData %p, start %d, count %d) \n " ,
iface , dstData , start , count ) ;
2010-03-28 23:51:07 +02:00
if ( dstData = = NULL | | ( ( signed int ) MAX_CONST_I - ( signed int ) start ) < = 0 )
2006-06-06 08:46:59 +02:00
return WINED3DERR_INVALIDCALL ;
2006-07-21 05:02:29 +02:00
memcpy ( dstData , & This - > stateBlock - > vertexShaderConstantI [ start * 4 ] , cnt * sizeof ( int ) * 4 ) ;
2006-06-06 08:46:59 +02:00
return WINED3D_OK ;
2005-12-20 11:46:52 +01:00
}
2005-09-21 12:19:29 +02:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
CONST float * srcData ,
UINT count ) {
2005-09-21 12:19:29 +02:00
2005-12-20 11:46:52 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2008-11-20 23:13:48 +01:00
UINT i ;
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, srcData %p, start %d, count %d) \n " ,
iface , srcData , start , count ) ;
2005-09-21 12:19:29 +02:00
2007-02-20 22:43:53 +01:00
/* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */
2009-03-22 12:24:28 +01:00
if ( srcData = = NULL | | start + count > This - > d3d_vshader_constantF | | start > This - > d3d_vshader_constantF )
2006-06-06 08:46:59 +02:00
return WINED3DERR_INVALIDCALL ;
2007-02-20 22:43:53 +01:00
memcpy ( & This - > updateStateBlock - > vertexShaderConstantF [ start * 4 ] , srcData , count * sizeof ( float ) * 4 ) ;
if ( TRACE_ON ( d3d ) ) {
for ( i = 0 ; i < count ; i + + )
TRACE ( " Set FLOAT constant %u to { %f, %f, %f, %f } \n " , start + i ,
srcData [ i * 4 ] , srcData [ i * 4 + 1 ] , srcData [ i * 4 + 2 ] , srcData [ i * 4 + 3 ] ) ;
}
2006-06-06 08:46:59 +02:00
2008-12-17 17:07:25 +01:00
if ( ! This - > isRecordingState )
{
2008-12-17 17:07:25 +01:00
This - > shader_backend - > shader_update_float_vertex_constants ( iface , start , count ) ;
2008-12-17 17:07:25 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VERTEXSHADERCONSTANT ) ;
}
2008-03-04 02:30:23 +01:00
2008-12-17 17:07:24 +01:00
memset ( This - > updateStateBlock - > changed . vertexShaderConstantsF + start , 1 ,
sizeof ( * This - > updateStateBlock - > changed . vertexShaderConstantsF ) * count ) ;
2008-03-04 02:30:23 +01:00
return WINED3D_OK ;
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
float * dstData ,
UINT count ) {
2005-12-20 11:46:52 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-22 12:24:28 +01:00
int cnt = min ( count , This - > d3d_vshader_constantF - start ) ;
2005-09-21 12:19:29 +02:00
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, dstData %p, start %d, count %d) \n " ,
iface , dstData , start , count ) ;
2005-03-02 13:16:10 +01:00
2006-06-06 08:46:59 +02:00
if ( dstData = = NULL | | cnt < 0 )
return WINED3DERR_INVALIDCALL ;
2006-07-21 05:02:29 +02:00
memcpy ( dstData , & This - > stateBlock - > vertexShaderConstantF [ start * 4 ] , cnt * sizeof ( float ) * 4 ) ;
2006-06-06 08:46:59 +02:00
return WINED3D_OK ;
2005-11-29 17:05:54 +01:00
}
2006-12-19 23:33:34 +01:00
static inline void markTextureStagesDirty ( IWineD3DDeviceImpl * This , DWORD stage ) {
DWORD i ;
2009-01-06 11:43:45 +01:00
for ( i = 0 ; i < = WINED3D_HIGHEST_TEXTURE_STATE ; + + i )
{
2006-12-19 23:33:34 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( stage , i ) ) ;
}
}
2009-08-17 09:39:07 +02:00
static void device_map_stage ( IWineD3DDeviceImpl * This , DWORD stage , DWORD unit )
{
DWORD i = This - > rev_tex_unit_map [ unit ] ;
DWORD j = This - > texUnitMap [ stage ] ;
2007-06-22 20:43:19 +02:00
This - > texUnitMap [ stage ] = unit ;
2009-08-17 09:39:07 +02:00
if ( i ! = WINED3D_UNMAPPED_STAGE & & i ! = stage )
{
This - > texUnitMap [ i ] = WINED3D_UNMAPPED_STAGE ;
2007-06-22 20:43:19 +02:00
}
This - > rev_tex_unit_map [ unit ] = stage ;
2009-08-17 09:39:07 +02:00
if ( j ! = WINED3D_UNMAPPED_STAGE & & j ! = unit )
{
This - > rev_tex_unit_map [ j ] = WINED3D_UNMAPPED_STAGE ;
2007-06-22 20:43:19 +02:00
}
}
2007-06-22 20:43:24 +02:00
static void device_update_fixed_function_usage_map ( IWineD3DDeviceImpl * This ) {
int i ;
2008-12-30 14:56:49 +01:00
This - > fixed_function_usage_map = 0 ;
2007-06-22 20:43:24 +02:00
for ( i = 0 ; i < MAX_TEXTURES ; + + i ) {
2007-06-27 23:47:24 +02:00
WINED3DTEXTUREOP color_op = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_COLOROP ] ;
WINED3DTEXTUREOP alpha_op = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_ALPHAOP ] ;
DWORD color_arg1 = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_COLORARG1 ] & WINED3DTA_SELECTMASK ;
DWORD color_arg2 = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_COLORARG2 ] & WINED3DTA_SELECTMASK ;
DWORD color_arg3 = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_COLORARG0 ] & WINED3DTA_SELECTMASK ;
DWORD alpha_arg1 = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_ALPHAARG1 ] & WINED3DTA_SELECTMASK ;
DWORD alpha_arg2 = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_ALPHAARG2 ] & WINED3DTA_SELECTMASK ;
DWORD alpha_arg3 = This - > stateBlock - > textureState [ i ] [ WINED3DTSS_ALPHAARG0 ] & WINED3DTA_SELECTMASK ;
if ( color_op = = WINED3DTOP_DISABLE ) {
/* Not used, and disable higher stages */
break ;
}
if ( ( ( color_arg1 = = WINED3DTA_TEXTURE ) & & color_op ! = WINED3DTOP_SELECTARG2 )
| | ( ( color_arg2 = = WINED3DTA_TEXTURE ) & & color_op ! = WINED3DTOP_SELECTARG1 )
| | ( ( color_arg3 = = WINED3DTA_TEXTURE ) & & ( color_op = = WINED3DTOP_MULTIPLYADD | | color_op = = WINED3DTOP_LERP ) )
| | ( ( alpha_arg1 = = WINED3DTA_TEXTURE ) & & alpha_op ! = WINED3DTOP_SELECTARG2 )
| | ( ( alpha_arg2 = = WINED3DTA_TEXTURE ) & & alpha_op ! = WINED3DTOP_SELECTARG1 )
| | ( ( alpha_arg3 = = WINED3DTA_TEXTURE ) & & ( alpha_op = = WINED3DTOP_MULTIPLYADD | | alpha_op = = WINED3DTOP_LERP ) ) ) {
2008-12-30 14:56:49 +01:00
This - > fixed_function_usage_map | = ( 1 < < i ) ;
2007-06-27 23:47:24 +02:00
}
if ( ( color_op = = WINED3DTOP_BUMPENVMAP | | color_op = = WINED3DTOP_BUMPENVMAPLUMINANCE ) & & i < MAX_TEXTURES - 1 ) {
2008-12-30 14:56:49 +01:00
This - > fixed_function_usage_map | = ( 1 < < ( i + 1 ) ) ;
2007-06-27 23:47:24 +02:00
}
2007-06-22 20:43:24 +02:00
}
}
2010-02-04 18:30:06 +01:00
static void device_map_fixed_function_samplers ( IWineD3DDeviceImpl * This , const struct wined3d_gl_info * gl_info )
{
2009-03-25 10:12:27 +01:00
unsigned int i , tex ;
2008-12-31 16:57:10 +01:00
WORD ffu_map ;
2007-06-22 20:43:29 +02:00
device_update_fixed_function_usage_map ( This ) ;
2008-12-31 16:57:10 +01:00
ffu_map = This - > fixed_function_usage_map ;
2007-06-22 20:43:29 +02:00
2010-02-04 18:30:06 +01:00
if ( This - > max_ffp_textures = = gl_info - > limits . texture_stages
| | This - > stateBlock - > lowest_disabled_stage < = This - > max_ffp_textures )
{
2008-12-31 16:57:10 +01:00
for ( i = 0 ; ffu_map ; ffu_map > > = 1 , + + i )
{
if ( ! ( ffu_map & 1 ) ) continue ;
2007-06-28 23:32:38 +02:00
2007-06-22 20:43:38 +02:00
if ( This - > texUnitMap [ i ] ! = i ) {
device_map_stage ( This , i , i ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( i ) ) ;
2007-06-28 23:32:38 +02:00
markTextureStagesDirty ( This , i ) ;
2007-06-22 20:43:38 +02:00
}
}
return ;
}
2007-06-22 20:43:29 +02:00
/* Now work out the mapping */
tex = 0 ;
2008-12-31 16:57:10 +01:00
for ( i = 0 ; ffu_map ; ffu_map > > = 1 , + + i )
{
if ( ! ( ffu_map & 1 ) ) continue ;
2007-06-22 20:43:29 +02:00
if ( This - > texUnitMap [ i ] ! = tex ) {
device_map_stage ( This , i , tex ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( i ) ) ;
markTextureStagesDirty ( This , i ) ;
}
+ + tex ;
}
}
2010-02-04 18:30:06 +01:00
static void device_map_psamplers ( IWineD3DDeviceImpl * This , const struct wined3d_gl_info * gl_info )
{
2009-04-29 09:55:06 +02:00
const WINED3DSAMPLER_TEXTURE_TYPE * sampler_type =
( ( IWineD3DPixelShaderImpl * ) This - > stateBlock - > pixelShader ) - > baseShader . reg_maps . sampler_type ;
2009-03-25 10:12:27 +01:00
unsigned int i ;
2007-06-22 20:43:42 +02:00
2007-06-25 22:45:40 +02:00
for ( i = 0 ; i < MAX_FRAGMENT_SAMPLERS ; + + i ) {
2009-04-29 09:55:06 +02:00
if ( sampler_type [ i ] & & This - > texUnitMap [ i ] ! = i )
{
2007-06-22 20:43:42 +02:00
device_map_stage ( This , i , i ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( i ) ) ;
2010-01-27 20:19:42 +01:00
if ( i < gl_info - > limits . texture_stages )
{
2007-06-22 20:43:42 +02:00
markTextureStagesDirty ( This , i ) ;
}
}
}
}
2008-11-26 16:14:39 +01:00
static BOOL device_unit_free_for_vs ( IWineD3DDeviceImpl * This , const DWORD * pshader_sampler_tokens ,
2009-08-17 09:39:07 +02:00
const DWORD * vshader_sampler_tokens , DWORD unit )
2008-11-26 16:14:39 +01:00
{
2009-08-17 09:39:07 +02:00
DWORD current_mapping = This - > rev_tex_unit_map [ unit ] ;
2007-06-27 23:47:06 +02:00
2009-08-17 09:39:07 +02:00
/* Not currently used */
if ( current_mapping = = WINED3D_UNMAPPED_STAGE ) return TRUE ;
2007-06-27 23:47:06 +02:00
if ( current_mapping < MAX_FRAGMENT_SAMPLERS ) {
/* Used by a fragment sampler */
if ( ! pshader_sampler_tokens ) {
/* No pixel shader, check fixed function */
2008-12-30 14:56:49 +01:00
return current_mapping > = MAX_TEXTURES | | ! ( This - > fixed_function_usage_map & ( 1 < < current_mapping ) ) ;
2007-06-27 23:47:06 +02:00
}
/* Pixel shader, check the shader's sampler map */
return ! pshader_sampler_tokens [ current_mapping ] ;
}
/* Used by a vertex sampler */
2009-08-17 09:39:06 +02:00
return ! vshader_sampler_tokens [ current_mapping - MAX_FRAGMENT_SAMPLERS ] ;
2007-06-27 23:47:06 +02:00
}
2010-02-04 18:30:06 +01:00
static void device_map_vsamplers ( IWineD3DDeviceImpl * This , BOOL ps , const struct wined3d_gl_info * gl_info )
{
2009-04-29 09:55:06 +02:00
const WINED3DSAMPLER_TEXTURE_TYPE * vshader_sampler_type =
( ( IWineD3DVertexShaderImpl * ) This - > stateBlock - > vertexShader ) - > baseShader . reg_maps . sampler_type ;
const WINED3DSAMPLER_TEXTURE_TYPE * pshader_sampler_type = NULL ;
2010-02-04 18:30:06 +01:00
int start = min ( MAX_COMBINED_SAMPLERS , gl_info - > limits . combined_samplers ) - 1 ;
2007-06-27 23:47:06 +02:00
int i ;
if ( ps ) {
IWineD3DPixelShaderImpl * pshader = ( IWineD3DPixelShaderImpl * ) This - > stateBlock - > pixelShader ;
2008-12-12 09:33:51 +01:00
/* 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 . */
2009-04-29 09:55:06 +02:00
pshader_sampler_type = pshader - > baseShader . reg_maps . sampler_type ;
2007-06-27 23:47:06 +02:00
}
for ( i = 0 ; i < MAX_VERTEX_SAMPLERS ; + + i ) {
2009-08-17 09:39:07 +02:00
DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS ;
2009-04-29 09:55:06 +02:00
if ( vshader_sampler_type [ i ] )
{
2009-03-09 14:31:28 +01:00
if ( This - > texUnitMap [ vsampler_idx ] ! = WINED3D_UNMAPPED_STAGE )
{
2007-06-27 23:47:06 +02:00
/* Already mapped somewhere */
continue ;
}
while ( start > = 0 ) {
2009-04-29 09:55:06 +02:00
if ( device_unit_free_for_vs ( This , pshader_sampler_type , vshader_sampler_type , start ) )
{
2007-06-27 23:47:06 +02:00
device_map_stage ( This , vsampler_idx , start ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( vsampler_idx ) ) ;
- - start ;
break ;
}
- - start ;
}
}
}
}
2010-02-04 18:30:06 +01:00
void IWineD3DDeviceImpl_FindTexUnitMap ( IWineD3DDeviceImpl * This )
{
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2008-12-30 14:56:49 +01:00
BOOL vs = use_vs ( This - > stateBlock ) ;
BOOL ps = use_ps ( This - > stateBlock ) ;
2007-07-01 23:40:57 +02:00
/*
2006-12-19 23:33:34 +01:00
* Rules are :
* - > Pixel shaders need a 1 : 1 map . In theory the shader input could be mapped too , but
* that would be really messy and require shader recompilation
* - > When the mapping of a stage is changed , sampler and ALL texture stage states have
* to be reset . Because of that try to work with a 1 : 1 mapping as much as possible
*/
2010-02-04 18:30:06 +01:00
if ( ps ) device_map_psamplers ( This , gl_info ) ;
else device_map_fixed_function_samplers ( This , gl_info ) ;
2007-06-27 23:47:06 +02:00
2010-02-04 18:30:06 +01:00
if ( vs ) device_map_vsamplers ( This , ps , gl_info ) ;
2006-12-19 23:33:34 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader ( IWineD3DDevice * iface , IWineD3DPixelShader * pShader ) {
2005-08-25 21:24:21 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-12-15 10:25:47 +01:00
IWineD3DPixelShader * oldShader = This - > updateStateBlock - > pixelShader ;
2005-08-25 21:24:21 +02:00
This - > updateStateBlock - > pixelShader = pShader ;
This - > updateStateBlock - > changed . pixelShader = TRUE ;
/* Handle recording of state blocks */
if ( This - > isRecordingState ) {
2005-11-21 17:27:55 +01:00
TRACE ( " Recording... not performing anything \n " ) ;
2005-08-25 21:24:21 +02:00
}
2005-12-13 11:11:01 +01:00
2006-12-19 23:22:19 +01:00
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
2007-08-20 18:56:10 +02:00
if ( pShader ) IWineD3DPixelShader_AddRef ( pShader ) ;
if ( oldShader ) IWineD3DPixelShader_Release ( oldShader ) ;
2006-12-19 23:22:19 +01:00
return WINED3D_OK ;
2005-12-15 10:25:47 +01:00
}
2006-12-19 23:22:48 +01:00
if ( pShader = = oldShader ) {
TRACE ( " App is setting the old pixel shader over, nothing to do \n " ) ;
return WINED3D_OK ;
}
2007-08-20 18:56:10 +02:00
if ( pShader ) IWineD3DPixelShader_AddRef ( pShader ) ;
if ( oldShader ) IWineD3DPixelShader_Release ( oldShader ) ;
2005-12-13 11:11:01 +01:00
TRACE ( " (%p) : setting pShader(%p) \n " , This , pShader ) ;
2006-12-19 23:22:19 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_PIXELSHADER ) ;
2006-12-19 23:33:34 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShader ( IWineD3DDevice * iface , IWineD3DPixelShader * * ppShader ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-08-25 21:24:21 +02:00
2005-11-21 17:27:55 +01:00
if ( NULL = = ppShader ) {
2005-08-25 21:24:21 +02:00
WARN ( " (%p) : PShader is NULL, returning INVALIDCALL \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-08-25 21:24:21 +02:00
}
2006-01-20 16:13:12 +01:00
* ppShader = This - > stateBlock - > pixelShader ;
2006-04-14 02:48:59 +02:00
if ( NULL ! = * ppShader ) {
2005-08-25 21:24:21 +02:00
IWineD3DPixelShader_AddRef ( * ppShader ) ;
}
TRACE ( " (%p) : returning %p \n " , This , * ppShader ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
CONST BOOL * srcData ,
UINT count ) {
2005-08-25 21:24:21 +02:00
2006-06-06 08:46:59 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-25 10:12:27 +01:00
unsigned int i , cnt = min ( count , MAX_CONST_B - start ) ;
2005-08-25 21:24:21 +02:00
2009-03-25 10:12:27 +01:00
TRACE ( " (iface %p, srcData %p, start %u, count %u) \n " ,
2006-06-06 08:46:59 +02:00
iface , srcData , start , count ) ;
2005-03-02 13:16:10 +01:00
2009-03-25 10:12:27 +01:00
if ( ! srcData | | start > = MAX_CONST_B ) return WINED3DERR_INVALIDCALL ;
2005-09-28 12:13:00 +02:00
2006-06-06 23:17:35 +02:00
memcpy ( & This - > updateStateBlock - > pixelShaderConstantB [ start ] , srcData , cnt * sizeof ( BOOL ) ) ;
2006-07-03 03:26:03 +02:00
for ( i = 0 ; i < cnt ; i + + )
2006-07-19 06:06:07 +02:00
TRACE ( " Set BOOL constant %u to %s \n " , start + i , srcData [ i ] ? " true " : " false " ) ;
2005-09-28 12:13:00 +02:00
2005-12-20 11:46:52 +01:00
for ( i = start ; i < cnt + start ; + + i ) {
2008-12-02 18:41:33 +01:00
This - > updateStateBlock - > changed . pixelShaderConstantsB | = ( 1 < < i ) ;
2005-08-25 21:24:21 +02:00
}
2005-09-28 12:13:00 +02:00
2008-12-17 17:07:25 +01:00
if ( ! This - > isRecordingState ) IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_PIXELSHADERCONSTANT ) ;
2007-01-06 18:17:27 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantB (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
BOOL * dstData ,
UINT count ) {
2005-09-28 12:13:00 +02:00
2006-06-06 08:46:59 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-07-19 06:06:07 +02:00
int cnt = min ( count , MAX_CONST_B - start ) ;
2005-12-20 11:46:52 +01:00
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, dstData %p, start %d, count %d) \n " ,
iface , dstData , start , count ) ;
2005-11-21 17:27:55 +01:00
2006-06-06 08:46:59 +02:00
if ( dstData = = NULL | | cnt < 0 )
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-09-28 12:13:00 +02:00
2006-07-21 05:02:29 +02:00
memcpy ( dstData , & This - > stateBlock - > pixelShaderConstantB [ start ] , cnt * sizeof ( BOOL ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
CONST int * srcData ,
UINT count ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-25 10:12:27 +01:00
unsigned int i , cnt = min ( count , MAX_CONST_I - start ) ;
2005-09-28 12:13:00 +02:00
2009-03-25 10:12:27 +01:00
TRACE ( " (iface %p, srcData %p, start %u, count %u) \n " ,
2006-06-06 08:46:59 +02:00
iface , srcData , start , count ) ;
2005-09-28 12:13:00 +02:00
2009-03-25 10:12:27 +01:00
if ( ! srcData | | start > = MAX_CONST_I ) return WINED3DERR_INVALIDCALL ;
2006-06-06 08:46:59 +02:00
2006-06-06 23:17:35 +02:00
memcpy ( & This - > updateStateBlock - > pixelShaderConstantI [ start * 4 ] , srcData , cnt * sizeof ( int ) * 4 ) ;
2006-07-03 03:26:03 +02:00
for ( i = 0 ; i < cnt ; i + + )
2006-07-19 06:06:07 +02:00
TRACE ( " Set INT constant %u to { %d, %d, %d, %d } \n " , start + i ,
2006-07-03 03:26:03 +02:00
srcData [ i * 4 ] , srcData [ i * 4 + 1 ] , srcData [ i * 4 + 2 ] , srcData [ i * 4 + 3 ] ) ;
2006-06-06 08:46:59 +02:00
for ( i = start ; i < cnt + start ; + + i ) {
2008-12-02 18:41:33 +01:00
This - > updateStateBlock - > changed . pixelShaderConstantsI | = ( 1 < < i ) ;
2006-06-06 08:46:59 +02:00
}
2005-09-28 12:13:00 +02:00
2008-12-17 17:07:25 +01:00
if ( ! This - > isRecordingState ) IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_PIXELSHADERCONSTANT ) ;
2007-01-06 18:17:27 +01:00
2006-06-06 08:46:59 +02:00
return WINED3D_OK ;
2005-12-20 11:46:52 +01:00
}
2005-09-28 12:13:00 +02:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantI (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
int * dstData ,
UINT count ) {
2005-12-20 11:46:52 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-07-19 06:06:07 +02:00
int cnt = min ( count , MAX_CONST_I - start ) ;
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, dstData %p, start %d, count %d) \n " ,
iface , dstData , start , count ) ;
if ( dstData = = NULL | | cnt < 0 )
return WINED3DERR_INVALIDCALL ;
2006-07-21 05:02:29 +02:00
memcpy ( dstData , & This - > stateBlock - > pixelShaderConstantI [ start * 4 ] , cnt * sizeof ( int ) * 4 ) ;
2006-06-06 08:46:59 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
CONST float * srcData ,
UINT count ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2008-11-20 23:13:48 +01:00
UINT i ;
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, srcData %p, start %d, count %d) \n " ,
iface , srcData , start , count ) ;
2007-02-20 22:43:53 +01:00
/* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */
2009-03-22 12:24:28 +01:00
if ( srcData = = NULL | | start + count > This - > d3d_pshader_constantF | | start > This - > d3d_pshader_constantF )
2006-06-06 08:46:59 +02:00
return WINED3DERR_INVALIDCALL ;
2007-02-20 22:43:53 +01:00
memcpy ( & This - > updateStateBlock - > pixelShaderConstantF [ start * 4 ] , srcData , count * sizeof ( float ) * 4 ) ;
if ( TRACE_ON ( d3d ) ) {
for ( i = 0 ; i < count ; i + + )
TRACE ( " Set FLOAT constant %u to { %f, %f, %f, %f } \n " , start + i ,
srcData [ i * 4 ] , srcData [ i * 4 + 1 ] , srcData [ i * 4 + 2 ] , srcData [ i * 4 + 3 ] ) ;
}
2006-06-06 08:46:59 +02:00
2008-12-17 17:07:25 +01:00
if ( ! This - > isRecordingState )
{
2008-12-17 17:07:25 +01:00
This - > shader_backend - > shader_update_float_pixel_constants ( iface , start , count ) ;
2008-12-17 17:07:25 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_PIXELSHADERCONSTANT ) ;
}
2008-03-04 02:30:23 +01:00
2008-12-17 17:07:24 +01:00
memset ( This - > updateStateBlock - > changed . pixelShaderConstantsF + start , 1 ,
sizeof ( * This - > updateStateBlock - > changed . pixelShaderConstantsF ) * count ) ;
2008-03-04 02:30:23 +01:00
return WINED3D_OK ;
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF (
2006-06-06 08:46:59 +02:00
IWineD3DDevice * iface ,
UINT start ,
float * dstData ,
UINT count ) {
2004-12-13 14:35:38 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-22 12:24:28 +01:00
int cnt = min ( count , This - > d3d_pshader_constantF - start ) ;
2005-09-28 12:13:00 +02:00
2006-06-06 08:46:59 +02:00
TRACE ( " (iface %p, dstData %p, start %d, count %d) \n " ,
iface , dstData , start , count ) ;
2004-12-13 14:35:38 +01:00
2006-06-06 08:46:59 +02:00
if ( dstData = = NULL | | cnt < 0 )
return WINED3DERR_INVALIDCALL ;
2006-07-21 05:02:29 +02:00
memcpy ( dstData , & This - > stateBlock - > pixelShaderConstantF [ start * 4 ] , cnt * sizeof ( float ) * 4 ) ;
2006-06-06 08:46:59 +02:00
return WINED3D_OK ;
2005-11-29 17:05:54 +01:00
}
2009-06-26 10:07:12 +02:00
/* Context activation is done by the caller. */
2006-05-12 22:21:31 +02:00
# define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
2008-11-26 16:14:39 +01:00
static HRESULT process_vertices_strided ( IWineD3DDeviceImpl * This , DWORD dwDestIndex , DWORD dwCount ,
2009-04-06 14:16:59 +02:00
const struct wined3d_stream_info * stream_info , struct wined3d_buffer * dest , DWORD dwFlags ,
DWORD DestFVF )
2008-11-26 16:14:39 +01:00
{
2009-10-29 10:37:11 +01:00
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2007-02-20 23:00:02 +01:00
char * dest_ptr , * dest_conv = NULL , * dest_conv_addr = NULL ;
2006-05-12 22:21:31 +02:00
unsigned int i ;
2006-10-11 03:57:25 +02:00
WINED3DVIEWPORT vp ;
2006-10-12 08:21:39 +02:00
WINED3DMATRIX mat , proj_mat , view_mat , world_mat ;
2006-05-12 22:21:31 +02:00
BOOL doClip ;
2008-11-20 23:13:48 +01:00
DWORD numTextures ;
2006-05-12 22:21:31 +02:00
2009-08-21 09:12:29 +02:00
if ( stream_info - > use_map & ( 1 < < WINED3D_FFP_NORMAL ) )
2009-03-27 10:25:55 +01:00
{
2006-05-12 22:21:31 +02:00
WARN ( " lighting state not saved yet... Some strange stuff may happen ! \n " ) ;
}
2009-08-21 09:12:29 +02:00
if ( ! ( stream_info - > use_map & ( 1 < < WINED3D_FFP_POSITION ) ) )
2009-03-27 10:25:55 +01:00
{
2006-05-12 22:21:31 +02:00
ERR ( " Source has no position mask \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
2006-06-21 15:05:38 +02:00
/* We might access VBOs from this code, so hold the lock */
ENTER_GL ( ) ;
2006-05-12 22:21:31 +02:00
if ( dest - > resource . allocatedMemory = = NULL ) {
2009-04-19 20:42:08 +02:00
buffer_get_sysmem ( dest ) ;
2006-06-21 15:05:38 +02:00
}
/* Get a pointer into the destination vbo(create one if none exists) and
* write correct opengl data into it . It ' s cheap and allows us to run drawStridedFast
*/
2009-10-29 10:37:11 +01:00
if ( ! dest - > buffer_object & & gl_info - > supported [ ARB_VERTEX_BUFFER_OBJECT ] )
2009-03-06 14:56:23 +01:00
{
dest - > flags | = WINED3D_BUFFER_CREATEBO ;
IWineD3DBuffer_PreLoad ( ( IWineD3DBuffer * ) dest ) ;
2006-06-21 15:05:38 +02:00
}
2009-03-06 14:56:23 +01:00
if ( dest - > buffer_object )
{
2007-05-06 18:39:29 +02:00
unsigned char extrabytes = 0 ;
/* If the destination vertex buffer has D3DFVF_XYZ position(non-rhw), native d3d writes RHW position, where the RHW
* gets written into the 4 bytes after the Z position . In the case of a dest buffer that only has D3DFVF_XYZ data ,
* this may write 4 extra bytes beyond the area that should be written
*/
if ( DestFVF = = WINED3DFVF_XYZ ) extrabytes = 4 ;
dest_conv_addr = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , dwCount * get_flexible_vertex_size ( DestFVF ) + extrabytes ) ;
2007-02-20 23:00:02 +01:00
if ( ! dest_conv_addr ) {
ERR ( " Out of memory \n " ) ;
2006-06-21 15:05:38 +02:00
/* Continue without storing converted vertices */
}
2007-02-20 23:00:02 +01:00
dest_conv = dest_conv_addr ;
2006-05-12 22:21:31 +02:00
}
/* Should I clip?
2006-10-12 08:19:57 +02:00
* a ) WINED3DRS_CLIPPING is enabled
2006-05-12 22:21:31 +02:00
* b ) WINED3DVOP_CLIP is passed
*/
2006-05-24 10:46:06 +02:00
if ( This - > stateBlock - > renderState [ WINED3DRS_CLIPPING ] ) {
2006-05-12 22:21:31 +02:00
static BOOL warned = FALSE ;
/*
* The clipping code is not quite correct . Some things need
* to be checked against IDirect3DDevice3 ( ! ) , d3d8 and d3d9 ,
* so disable clipping for now .
* ( The graphics in Half - Life are broken , and my processvertices
* test crashes with IDirect3DDevice3 )
doClip = TRUE ;
*/
doClip = FALSE ;
if ( ! warned ) {
warned = TRUE ;
FIXME ( " Clipping is broken and disabled for now \n " ) ;
}
} else doClip = FALSE ;
2009-04-09 18:40:57 +02:00
dest_ptr = ( ( char * ) buffer_get_sysmem ( dest ) ) + dwDestIndex * get_flexible_vertex_size ( DestFVF ) ;
2006-05-12 22:21:31 +02:00
IWineD3DDevice_GetTransform ( ( IWineD3DDevice * ) This ,
2006-07-24 04:54:30 +02:00
WINED3DTS_VIEW ,
2006-05-12 22:21:31 +02:00
& view_mat ) ;
IWineD3DDevice_GetTransform ( ( IWineD3DDevice * ) This ,
2006-07-24 04:54:30 +02:00
WINED3DTS_PROJECTION ,
2006-05-12 22:21:31 +02:00
& proj_mat ) ;
IWineD3DDevice_GetTransform ( ( IWineD3DDevice * ) This ,
2006-07-24 04:54:30 +02:00
WINED3DTS_WORLDMATRIX ( 0 ) ,
2006-05-12 22:21:31 +02:00
& world_mat ) ;
2006-06-15 17:41:17 +02:00
TRACE ( " View mat: \n " ) ;
2007-01-09 00:39:30 +01:00
TRACE ( " %f %f %f %f \n " , view_mat . u . s . _11 , view_mat . u . s . _12 , view_mat . u . s . _13 , view_mat . u . s . _14 ) ;
TRACE ( " %f %f %f %f \n " , view_mat . u . s . _21 , view_mat . u . s . _22 , view_mat . u . s . _23 , view_mat . u . s . _24 ) ;
TRACE ( " %f %f %f %f \n " , view_mat . u . s . _31 , view_mat . u . s . _32 , view_mat . u . s . _33 , view_mat . u . s . _34 ) ;
TRACE ( " %f %f %f %f \n " , view_mat . u . s . _41 , view_mat . u . s . _42 , view_mat . u . s . _43 , view_mat . u . s . _44 ) ;
2006-05-12 22:21:31 +02:00
2006-06-15 17:41:17 +02:00
TRACE ( " Proj mat: \n " ) ;
2007-01-09 00:39:30 +01:00
TRACE ( " %f %f %f %f \n " , proj_mat . u . s . _11 , proj_mat . u . s . _12 , proj_mat . u . s . _13 , proj_mat . u . s . _14 ) ;
TRACE ( " %f %f %f %f \n " , proj_mat . u . s . _21 , proj_mat . u . s . _22 , proj_mat . u . s . _23 , proj_mat . u . s . _24 ) ;
TRACE ( " %f %f %f %f \n " , proj_mat . u . s . _31 , proj_mat . u . s . _32 , proj_mat . u . s . _33 , proj_mat . u . s . _34 ) ;
TRACE ( " %f %f %f %f \n " , proj_mat . u . s . _41 , proj_mat . u . s . _42 , proj_mat . u . s . _43 , proj_mat . u . s . _44 ) ;
2006-05-12 22:21:31 +02:00
2006-06-15 17:41:17 +02:00
TRACE ( " World mat: \n " ) ;
2007-01-09 00:39:30 +01:00
TRACE ( " %f %f %f %f \n " , world_mat . u . s . _11 , world_mat . u . s . _12 , world_mat . u . s . _13 , world_mat . u . s . _14 ) ;
TRACE ( " %f %f %f %f \n " , world_mat . u . s . _21 , world_mat . u . s . _22 , world_mat . u . s . _23 , world_mat . u . s . _24 ) ;
TRACE ( " %f %f %f %f \n " , world_mat . u . s . _31 , world_mat . u . s . _32 , world_mat . u . s . _33 , world_mat . u . s . _34 ) ;
TRACE ( " %f %f %f %f \n " , world_mat . u . s . _41 , world_mat . u . s . _42 , world_mat . u . s . _43 , world_mat . u . s . _44 ) ;
2006-05-12 22:21:31 +02:00
/* Get the viewport */
IWineD3DDevice_GetViewport ( ( IWineD3DDevice * ) This , & vp ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " Viewport: X=%d, Y=%d, Width=%d, Height=%d, MinZ=%f, MaxZ=%f \n " ,
2006-05-12 22:21:31 +02:00
vp . X , vp . Y , vp . Width , vp . Height , vp . MinZ , vp . MaxZ ) ;
multiply_matrix ( & mat , & view_mat , & world_mat ) ;
multiply_matrix ( & mat , & proj_mat , & mat ) ;
2006-10-31 09:16:08 +01:00
numTextures = ( DestFVF & WINED3DFVF_TEXCOUNT_MASK ) > > WINED3DFVF_TEXCOUNT_SHIFT ;
2006-05-12 22:21:31 +02:00
for ( i = 0 ; i < dwCount ; i + = 1 ) {
unsigned int tex_index ;
2006-10-31 09:16:08 +01:00
if ( ( ( DestFVF & WINED3DFVF_POSITION_MASK ) = = WINED3DFVF_XYZ ) | |
( ( DestFVF & WINED3DFVF_POSITION_MASK ) = = WINED3DFVF_XYZRHW ) ) {
2006-05-12 22:21:31 +02:00
/* The position first */
2009-03-27 10:25:55 +01:00
const struct wined3d_stream_info_element * element = & stream_info - > elements [ WINED3D_FFP_POSITION ] ;
const float * p = ( const float * ) ( element - > data + i * element - > stride ) ;
2006-05-12 22:21:31 +02:00
float x , y , z , rhw ;
TRACE ( " In: ( %06.2f %06.2f %06.2f ) \n " , p [ 0 ] , p [ 1 ] , p [ 2 ] ) ;
/* Multiplication with world, view and projection matrix */
2009-07-07 11:08:01 +02:00
x = ( p [ 0 ] * mat . u . s . _11 ) + ( p [ 1 ] * mat . u . s . _21 ) + ( p [ 2 ] * mat . u . s . _31 ) + ( 1.0f * mat . u . s . _41 ) ;
y = ( p [ 0 ] * mat . u . s . _12 ) + ( p [ 1 ] * mat . u . s . _22 ) + ( p [ 2 ] * mat . u . s . _32 ) + ( 1.0f * mat . u . s . _42 ) ;
z = ( p [ 0 ] * mat . u . s . _13 ) + ( p [ 1 ] * mat . u . s . _23 ) + ( p [ 2 ] * mat . u . s . _33 ) + ( 1.0f * mat . u . s . _43 ) ;
rhw = ( p [ 0 ] * mat . u . s . _14 ) + ( p [ 1 ] * mat . u . s . _24 ) + ( p [ 2 ] * mat . u . s . _34 ) + ( 1.0f * mat . u . s . _44 ) ;
2006-05-12 22:21:31 +02:00
TRACE ( " x=%f y=%f z=%f rhw=%f \n " , x , y , z , rhw ) ;
/* WARNING: The following things are taken from d3d7 and were not yet checked
* against d3d8 or d3d9 !
*/
2008-03-01 05:34:39 +01:00
/* Clipping conditions: From msdn
2006-05-12 22:21:31 +02:00
*
* A vertex is clipped if it does not match the following requirements
* - rhw < x < = rhw
* - rhw < y < = rhw
* 0 < z < = rhw
* 0 < rhw ( Not in d3d7 , but tested in d3d7 )
*
* If clipping is on is determined by the D3DVOP_CLIP flag in D3D7 , and
* by the D3DRS_CLIPPING in D3D9 ( according to the msdn , not checked )
*
*/
2006-09-26 20:31:58 +02:00
if ( ! doClip | |
2006-05-12 22:21:31 +02:00
( ( - rhw - eps < x ) & & ( - rhw - eps < y ) & & ( - eps < z ) & &
2009-08-27 10:04:56 +02:00
( x < = rhw + eps ) & & ( y < = rhw + eps ) & & ( z < = rhw + eps ) & &
2006-05-12 22:21:31 +02:00
( rhw > eps ) ) ) {
/* "Normal" viewport transformation (not clipped)
2006-06-15 17:38:04 +02:00
* 1 ) The values are divided by rhw
2006-05-12 22:21:31 +02:00
* 2 ) The y axis is negative , so multiply it with - 1
* 3 ) Screen coordinates go from - ( Width / 2 ) to + ( Width / 2 ) and
* - ( Height / 2 ) to + ( Height / 2 ) . The z range is MinZ to MaxZ
* 4 ) Multiply x with Width / 2 and add Width / 2
* 5 ) The same for the height
* 6 ) Add the viewpoint X and Y to the 2 D coordinates and
* The minimum Z value to z
* 7 ) rhw = 1 / rhw Reciprocal of Homogeneous W . . . .
*
* Well , basically it ' s simply a linear transformation into viewport
* coordinates
*/
x / = rhw ;
y / = rhw ;
z / = rhw ;
y * = - 1 ;
x * = vp . Width / 2 ;
y * = vp . Height / 2 ;
z * = vp . MaxZ - vp . MinZ ;
x + = vp . Width / 2 + vp . X ;
y + = vp . Height / 2 + vp . Y ;
z + = vp . MinZ ;
rhw = 1 / rhw ;
} else {
/* That vertex got clipped
* Contrary to OpenGL it is not dropped completely , it just
* undergoes a different calculation .
*/
TRACE ( " Vertex got clipped \n " ) ;
x + = rhw ;
y + = rhw ;
x / = 2 ;
y / = 2 ;
2006-06-23 18:18:02 +02:00
/* Msdn mentions that Direct3D9 keeps a list of clipped vertices
2006-05-12 22:21:31 +02:00
* outside of the main vertex buffer memory . That needs some more
* investigation . . .
*/
}
TRACE ( " Writing (%f %f %f) %f \n " , x , y , z , rhw ) ;
( ( float * ) dest_ptr ) [ 0 ] = x ;
( ( float * ) dest_ptr ) [ 1 ] = y ;
( ( float * ) dest_ptr ) [ 2 ] = z ;
( ( float * ) dest_ptr ) [ 3 ] = rhw ; /* SIC, see ddraw test! */
dest_ptr + = 3 * sizeof ( float ) ;
2006-10-31 09:16:08 +01:00
if ( ( DestFVF & WINED3DFVF_POSITION_MASK ) = = WINED3DFVF_XYZRHW ) {
2006-05-12 22:21:31 +02:00
dest_ptr + = sizeof ( float ) ;
}
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
float w = 1 / rhw ;
( ( float * ) dest_conv ) [ 0 ] = x * w ;
( ( float * ) dest_conv ) [ 1 ] = y * w ;
( ( float * ) dest_conv ) [ 2 ] = z * w ;
( ( float * ) dest_conv ) [ 3 ] = w ;
dest_conv + = 3 * sizeof ( float ) ;
2006-10-31 09:16:08 +01:00
if ( ( DestFVF & WINED3DFVF_POSITION_MASK ) = = WINED3DFVF_XYZRHW ) {
2006-06-21 15:05:38 +02:00
dest_conv + = sizeof ( float ) ;
}
}
2006-05-12 22:21:31 +02:00
}
2006-10-31 09:16:08 +01:00
if ( DestFVF & WINED3DFVF_PSIZE ) {
2006-05-12 22:21:31 +02:00
dest_ptr + = sizeof ( DWORD ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) dest_conv + = sizeof ( DWORD ) ;
2006-05-12 22:21:31 +02:00
}
2006-10-31 09:16:08 +01:00
if ( DestFVF & WINED3DFVF_NORMAL ) {
2009-03-27 10:25:55 +01:00
const struct wined3d_stream_info_element * element = & stream_info - > elements [ WINED3D_FFP_NORMAL ] ;
const float * normal = ( const float * ) ( element - > data + i * element - > stride ) ;
2006-05-12 22:21:31 +02:00
/* AFAIK this should go into the lighting information */
FIXME ( " Didn't expect the destination to have a normal \n " ) ;
copy_and_next ( dest_ptr , normal , 3 * sizeof ( float ) ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
copy_and_next ( dest_conv , normal , 3 * sizeof ( float ) ) ;
}
2006-05-12 22:21:31 +02:00
}
2006-10-31 09:16:08 +01:00
if ( DestFVF & WINED3DFVF_DIFFUSE ) {
2009-03-27 10:25:55 +01:00
const struct wined3d_stream_info_element * element = & stream_info - > elements [ WINED3D_FFP_DIFFUSE ] ;
const DWORD * color_d = ( const DWORD * ) ( element - > data + i * element - > stride ) ;
2009-08-21 09:12:29 +02:00
if ( ! ( stream_info - > use_map & ( 1 < < WINED3D_FFP_DIFFUSE ) ) )
{
2006-05-12 22:21:31 +02:00
static BOOL warned = FALSE ;
2006-09-26 20:31:58 +02:00
if ( ! warned ) {
2006-05-12 22:21:31 +02:00
ERR ( " No diffuse color in source, but destination has one \n " ) ;
warned = TRUE ;
}
* ( ( DWORD * ) dest_ptr ) = 0xffffffff ;
dest_ptr + = sizeof ( DWORD ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
* ( ( DWORD * ) dest_conv ) = 0xffffffff ;
dest_conv + = sizeof ( DWORD ) ;
}
2006-05-12 22:21:31 +02:00
}
2006-06-21 15:05:38 +02:00
else {
2006-05-12 22:21:31 +02:00
copy_and_next ( dest_ptr , color_d , sizeof ( DWORD ) ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
* ( ( DWORD * ) dest_conv ) = ( * color_d & 0xff00ff00 ) ; /* Alpha + green */
* ( ( DWORD * ) dest_conv ) | = ( * color_d & 0x00ff0000 ) > > 16 ; /* Red */
* ( ( DWORD * ) dest_conv ) | = ( * color_d & 0xff0000ff ) < < 16 ; /* Blue */
dest_conv + = sizeof ( DWORD ) ;
}
}
2006-05-12 22:21:31 +02:00
}
2009-08-27 10:04:56 +02:00
if ( DestFVF & WINED3DFVF_SPECULAR )
{
2006-05-12 22:21:31 +02:00
/* What's the color value in the feedback buffer? */
2009-03-27 10:25:55 +01:00
const struct wined3d_stream_info_element * element = & stream_info - > elements [ WINED3D_FFP_SPECULAR ] ;
const DWORD * color_s = ( const DWORD * ) ( element - > data + i * element - > stride ) ;
2009-08-21 09:12:29 +02:00
if ( ! ( stream_info - > use_map & ( 1 < < WINED3D_FFP_SPECULAR ) ) )
{
2006-05-12 22:21:31 +02:00
static BOOL warned = FALSE ;
2006-09-26 20:31:58 +02:00
if ( ! warned ) {
2006-05-12 22:21:31 +02:00
ERR ( " No specular color in source, but destination has one \n " ) ;
warned = TRUE ;
}
* ( ( DWORD * ) dest_ptr ) = 0xFF000000 ;
dest_ptr + = sizeof ( DWORD ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
* ( ( DWORD * ) dest_conv ) = 0xFF000000 ;
dest_conv + = sizeof ( DWORD ) ;
}
2006-05-12 22:21:31 +02:00
}
else {
copy_and_next ( dest_ptr , color_s , sizeof ( DWORD ) ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
* ( ( DWORD * ) dest_conv ) = ( * color_s & 0xff00ff00 ) ; /* Alpha + green */
* ( ( DWORD * ) dest_conv ) | = ( * color_s & 0x00ff0000 ) > > 16 ; /* Red */
* ( ( DWORD * ) dest_conv ) | = ( * color_s & 0xff0000ff ) < < 16 ; /* Blue */
dest_conv + = sizeof ( DWORD ) ;
}
2006-05-12 22:21:31 +02:00
}
}
for ( tex_index = 0 ; tex_index < numTextures ; tex_index + + ) {
2009-03-27 10:25:55 +01:00
const struct wined3d_stream_info_element * element = & stream_info - > elements [ WINED3D_FFP_TEXCOORD0 + tex_index ] ;
const float * tex_coord = ( const float * ) ( element - > data + i * element - > stride ) ;
2009-08-21 09:12:29 +02:00
if ( ! ( stream_info - > use_map & ( 1 < < ( WINED3D_FFP_TEXCOORD0 + tex_index ) ) ) )
{
2006-05-12 22:21:31 +02:00
ERR ( " No source texture, but destination requests one \n " ) ;
dest_ptr + = GET_TEXCOORD_SIZE_FROM_FVF ( DestFVF , tex_index ) * sizeof ( float ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) dest_conv + = GET_TEXCOORD_SIZE_FROM_FVF ( DestFVF , tex_index ) * sizeof ( float ) ;
2006-05-12 22:21:31 +02:00
}
else {
copy_and_next ( dest_ptr , tex_coord , GET_TEXCOORD_SIZE_FROM_FVF ( DestFVF , tex_index ) * sizeof ( float ) ) ;
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
copy_and_next ( dest_conv , tex_coord , GET_TEXCOORD_SIZE_FROM_FVF ( DestFVF , tex_index ) * sizeof ( float ) ) ;
}
2006-05-12 22:21:31 +02:00
}
}
}
2006-06-21 15:05:38 +02:00
if ( dest_conv ) {
2009-03-06 14:56:23 +01:00
GL_EXTCALL ( glBindBufferARB ( GL_ARRAY_BUFFER_ARB , dest - > buffer_object ) ) ;
2007-02-20 23:00:02 +01:00
checkGLcall ( " glBindBufferARB(GL_ARRAY_BUFFER_ARB) " ) ;
GL_EXTCALL ( glBufferSubDataARB ( GL_ARRAY_BUFFER_ARB , dwDestIndex * get_flexible_vertex_size ( DestFVF ) ,
dwCount * get_flexible_vertex_size ( DestFVF ) ,
dest_conv_addr ) ) ;
checkGLcall ( " glBufferSubDataARB(GL_ARRAY_BUFFER_ARB) " ) ;
HeapFree ( GetProcessHeap ( ) , 0 , dest_conv_addr ) ;
2006-06-21 15:05:38 +02:00
}
LEAVE_GL ( ) ;
2006-05-12 22:21:31 +02:00
return WINED3D_OK ;
}
# undef copy_and_next
2009-03-06 14:56:23 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices ( IWineD3DDevice * iface , UINT SrcStartIndex , UINT DestIndex ,
2009-04-06 14:16:59 +02:00
UINT VertexCount , IWineD3DBuffer * pDestBuffer , IWineD3DVertexDeclaration * pVertexDecl , DWORD Flags ,
DWORD DestFVF )
2009-03-06 14:56:23 +01:00
{
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-27 10:25:55 +01:00
struct wined3d_stream_info stream_info ;
2009-10-28 11:00:11 +01:00
struct wined3d_context * context ;
2007-04-29 17:36:35 +02:00
BOOL vbo = FALSE , streamWasUP = This - > stateBlock - > streamIsUP ;
2009-10-28 11:00:11 +01:00
HRESULT hr ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p)->(%d,%d,%d,%p,%p,%d \n " , This , SrcStartIndex , DestIndex , VertexCount , pDestBuffer , pVertexDecl , Flags ) ;
2006-05-12 22:21:31 +02:00
2007-04-22 18:06:07 +02:00
if ( pVertexDecl ) {
ERR ( " Output vertex declaration not implemented yet \n " ) ;
2006-09-04 16:16:45 +02:00
}
2007-03-17 23:00:39 +01:00
2008-01-02 19:51:51 +01:00
/* Need any context to write to the vbo. */
2009-10-28 11:00:11 +01:00
context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2007-03-17 23:00:39 +01:00
2007-04-29 17:36:35 +02:00
/* ProcessVertices reads from vertex buffers, which have to be assigned. DrawPrimitive and DrawPrimitiveUP
* control the streamIsUP flag , thus restore it afterwards .
*/
This - > stateBlock - > streamIsUP = FALSE ;
2009-03-27 10:25:55 +01:00
device_stream_info_from_declaration ( This , FALSE , & stream_info , & vbo ) ;
2007-04-29 17:36:35 +02:00
This - > stateBlock - > streamIsUP = streamWasUP ;
2006-06-21 15:05:38 +02:00
2007-04-22 18:06:07 +02:00
if ( vbo | | SrcStartIndex ) {
unsigned int i ;
2008-01-09 20:37:05 +01:00
/* ProcessVertices can't convert FROM a vbo, and vertex buffers used to source into ProcessVertices are
2009-03-27 10:25:55 +01:00
* unlikely to ever be used for drawing . Release vbos in those buffers and fix up the stream_info structure
2007-04-22 18:06:07 +02:00
*
* Also get the start index in , but only loop over all elements if there ' s something to add at all .
*/
2009-03-27 10:25:55 +01:00
for ( i = 0 ; i < ( sizeof ( stream_info . elements ) / sizeof ( * stream_info . elements ) ) ; + + i )
2009-03-26 10:43:40 +01:00
{
2009-08-21 09:12:29 +02:00
struct wined3d_stream_info_element * e ;
if ( ! ( stream_info . use_map & ( 1 < < i ) ) ) continue ;
e = & stream_info . elements [ i ] ;
2009-03-27 10:25:55 +01:00
if ( e - > buffer_object )
2009-03-26 10:43:40 +01:00
{
2009-03-27 10:25:55 +01:00
struct wined3d_buffer * vb = ( struct wined3d_buffer * ) This - > stateBlock - > streamSource [ e - > stream_idx ] ;
e - > buffer_object = 0 ;
2009-04-09 18:40:57 +02:00
e - > data = ( BYTE * ) ( ( unsigned long ) e - > data + ( unsigned long ) buffer_get_sysmem ( vb ) ) ;
2009-03-26 10:43:40 +01:00
ENTER_GL ( ) ;
GL_EXTCALL ( glDeleteBuffersARB ( 1 , & vb - > buffer_object ) ) ;
vb - > buffer_object = 0 ;
LEAVE_GL ( ) ;
}
2009-03-27 10:25:55 +01:00
if ( e - > data ) e - > data + = e - > stride * SrcStartIndex ;
2006-06-21 15:05:38 +02:00
}
}
2009-10-28 11:00:11 +01:00
hr = process_vertices_strided ( This , DestIndex , VertexCount , & stream_info ,
2009-04-06 14:16:59 +02:00
( struct wined3d_buffer * ) pDestBuffer , Flags , DestFVF ) ;
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
return hr ;
2005-03-02 13:16:10 +01:00
}
2004-12-13 14:35:38 +01:00
2005-08-22 11:13:49 +02:00
/*****
* Get / Set Texture Stage States
* TODO : Verify against dx9 definitions
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState ( IWineD3DDevice * iface , DWORD Stage , WINED3DTEXTURESTAGESTATETYPE Type , DWORD Value ) {
2005-08-01 12:58:31 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-12-19 23:12:26 +01:00
DWORD oldValue = This - > updateStateBlock - > textureState [ Stage ] [ Type ] ;
2010-01-27 20:19:42 +01:00
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2005-08-01 12:58:31 +02:00
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Stage=%d, Type=%s(%d), Value=%d \n " , This , Stage , debug_d3dtexturestate ( Type ) , Type , Value ) ;
2005-08-01 12:58:31 +02:00
2010-01-27 20:19:42 +01:00
if ( Stage > = gl_info - > limits . texture_stages )
{
WARN ( " Attempting to set stage %u which is higher than the max stage %u, ignoring. \n " ,
Stage , gl_info - > limits . texture_stages - 1 ) ;
2007-04-16 21:44:27 +02:00
return WINED3D_OK ;
}
2009-01-06 11:43:45 +01:00
This - > updateStateBlock - > changed . textureState [ Stage ] | = 1 < < Type ;
2005-08-01 12:58:31 +02:00
This - > updateStateBlock - > textureState [ Stage ] [ Type ] = Value ;
2006-12-19 23:00:58 +01:00
if ( This - > isRecordingState ) {
TRACE ( " Recording... not performing anything \n " ) ;
return WINED3D_OK ;
}
2006-12-19 23:12:26 +01:00
/* Checked after the assignments to allow proper stateblock recording */
if ( oldValue = = Value ) {
TRACE ( " App is setting the old value over, nothing to do \n " ) ;
return WINED3D_OK ;
}
2006-12-19 23:00:58 +01:00
if ( Stage > This - > stateBlock - > lowest_disabled_stage & &
2008-07-02 01:23:44 +02:00
This - > StateTable [ STATE_TEXTURESTAGE ( 0 , Type ) ] . representative = = STATE_TEXTURESTAGE ( 0 , WINED3DTSS_COLOROP ) ) {
2006-12-19 23:00:58 +01:00
/* Colorop change above lowest disabled stage? That won't change anything in the gl setup
* Changes in other states are important on disabled stages too
*/
return WINED3D_OK ;
}
if ( Type = = WINED3DTSS_COLOROP ) {
2009-03-25 10:12:27 +01:00
unsigned int i ;
2006-12-19 23:00:58 +01:00
2006-12-19 23:12:26 +01:00
if ( Value = = WINED3DTOP_DISABLE & & oldValue ! = WINED3DTOP_DISABLE ) {
2006-12-19 23:00:58 +01:00
/* Previously enabled stage disabled now. Make sure to dirtify all enabled stages above Stage,
* they have to be disabled
*
* The current stage is dirtified below .
*/
for ( i = Stage + 1 ; i < This - > stateBlock - > lowest_disabled_stage ; i + + ) {
2009-03-25 10:12:27 +01:00
TRACE ( " Additionally dirtifying stage %u \n " , i ) ;
2006-12-19 23:00:58 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( i , WINED3DTSS_COLOROP ) ) ;
}
This - > stateBlock - > lowest_disabled_stage = Stage ;
2009-03-25 10:12:27 +01:00
TRACE ( " New lowest disabled: %u \n " , Stage ) ;
2006-12-19 23:12:26 +01:00
} else if ( Value ! = WINED3DTOP_DISABLE & & oldValue = = WINED3DTOP_DISABLE ) {
2006-12-19 23:00:58 +01:00
/* Previously disabled stage enabled. Stages above it may need enabling
* stage must be lowest_disabled_stage here , if it ' s bigger success is returned above ,
* and stages below the lowest disabled stage can ' t be enabled ( because they are enabled already ) .
*
* Again stage Stage doesn ' t need to be dirtified here , it is handled below .
*/
2009-10-29 10:37:10 +01:00
for ( i = Stage + 1 ; i < This - > adapter - > gl_info . limits . texture_stages ; + + i )
2009-10-22 10:09:54 +02:00
{
2006-12-19 23:00:58 +01:00
if ( This - > updateStateBlock - > textureState [ i ] [ WINED3DTSS_COLOROP ] = = WINED3DTOP_DISABLE ) {
break ;
}
2009-03-25 10:12:27 +01:00
TRACE ( " Additionally dirtifying stage %u due to enable \n " , i ) ;
2006-12-19 23:00:58 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( i , WINED3DTSS_COLOROP ) ) ;
}
This - > stateBlock - > lowest_disabled_stage = i ;
2009-03-25 10:12:27 +01:00
TRACE ( " New lowest disabled: %u \n " , i ) ;
2006-12-19 23:00:58 +01:00
}
}
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( Stage , Type ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-13 14:35:38 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetTextureStageState ( IWineD3DDevice * iface , DWORD Stage , WINED3DTEXTURESTAGESTATETYPE Type , DWORD * pValue ) {
2004-12-13 14:35:38 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : requesting Stage %d, Type %d getting %d \n " , This , Stage , Type , This - > updateStateBlock - > textureState [ Stage ] [ Type ] ) ;
2004-12-13 14:35:38 +01:00
* pValue = This - > updateStateBlock - > textureState [ Stage ] [ Type ] ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-13 14:35:38 +01:00
}
2005-01-18 12:42:29 +01:00
/*****
2005-07-13 16:15:54 +02:00
* Get / Set Texture
2005-01-18 12:42:29 +01:00
* * * * */
2009-09-28 10:05:02 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture ( IWineD3DDevice * iface ,
DWORD stage , IWineD3DBaseTexture * texture )
{
2005-01-18 12:42:29 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2010-01-27 20:19:42 +01:00
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2009-09-28 10:05:02 +02:00
IWineD3DBaseTexture * prev ;
2005-01-18 12:42:29 +01:00
2009-09-28 10:05:02 +02:00
TRACE ( " iface %p, stage %u, texture %p. \n " , iface , stage , texture ) ;
2005-01-18 12:42:29 +01:00
2009-09-28 10:05:02 +02:00
if ( stage > = WINED3DVERTEXTEXTURESAMPLER0 & & stage < = WINED3DVERTEXTEXTURESAMPLER3 )
stage - = ( WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS ) ;
2007-06-25 22:46:01 +02:00
2009-09-28 10:05:02 +02:00
/* Windows accepts overflowing this array... we do not. */
if ( stage > = sizeof ( This - > stateBlock - > textures ) / sizeof ( * This - > stateBlock - > textures ) )
{
WARN ( " Ignoring invalid stage %u. \n " , stage ) ;
return WINED3D_OK ;
2008-01-15 08:06:37 +01:00
}
2008-12-12 09:33:51 +01:00
/* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH */
2009-09-28 10:05:02 +02:00
if ( texture & & ( ( IWineD3DTextureImpl * ) texture ) - > resource . pool = = WINED3DPOOL_SCRATCH )
2008-12-12 09:33:51 +01:00
{
2009-09-28 10:05:02 +02:00
WARN ( " Rejecting attempt to set scratch texture. \n " ) ;
2008-12-12 09:33:51 +01:00
return WINED3DERR_INVALIDCALL ;
2006-02-06 20:57:42 +01:00
}
2009-09-28 10:05:02 +02:00
This - > updateStateBlock - > changed . textures | = 1 < < stage ;
2009-09-28 10:04:59 +02:00
2009-09-28 10:05:02 +02:00
prev = This - > updateStateBlock - > textures [ stage ] ;
TRACE ( " Previous texture %p. \n " , prev ) ;
2009-09-28 10:04:59 +02:00
2009-09-28 10:05:02 +02:00
if ( texture = = prev )
{
TRACE ( " App is setting the same texture again, nothing to do. \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-18 12:42:29 +01:00
}
2009-09-28 10:05:02 +02:00
TRACE ( " Setting new texture to %p. \n " , texture ) ;
This - > updateStateBlock - > textures [ stage ] = texture ;
if ( This - > isRecordingState )
{
TRACE ( " Recording... not performing anything \n " ) ;
if ( texture ) IWineD3DBaseTexture_AddRef ( texture ) ;
if ( prev ) IWineD3DBaseTexture_Release ( prev ) ;
2006-12-19 23:17:17 +01:00
return WINED3D_OK ;
}
2009-09-28 10:05:02 +02:00
if ( texture )
{
IWineD3DBaseTextureImpl * t = ( IWineD3DBaseTextureImpl * ) texture ;
LONG bind_count = InterlockedIncrement ( & t - > baseTexture . bindCount ) ;
UINT dimensions = IWineD3DBaseTexture_GetTextureDimensions ( texture ) ;
2006-12-19 23:26:39 +01:00
2009-09-28 10:05:02 +02:00
IWineD3DBaseTexture_AddRef ( texture ) ;
2009-01-12 10:17:50 +01:00
2009-09-28 10:05:02 +02:00
if ( ! prev | | dimensions ! = IWineD3DBaseTexture_GetTextureDimensions ( prev ) )
2009-01-12 10:17:50 +01:00
{
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_PIXELSHADER ) ;
}
2010-01-27 20:19:42 +01:00
if ( ! prev & & stage < gl_info - > limits . texture_stages )
2009-09-28 10:05:02 +02:00
{
/* The source arguments for color and alpha ops have different
* meanings when a NULL texture is bound , so the COLOROP and
* ALPHAOP have to be dirtified . */
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( stage , WINED3DTSS_COLOROP ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( stage , WINED3DTSS_ALPHAOP ) ) ;
2006-12-19 23:26:39 +01:00
}
2009-09-28 10:05:02 +02:00
if ( bind_count = = 1 ) t - > baseTexture . sampler = stage ;
2005-07-26 20:49:30 +02:00
}
2005-03-14 11:12:52 +01:00
2009-09-28 10:05:02 +02:00
if ( prev )
{
IWineD3DBaseTextureImpl * t = ( IWineD3DBaseTextureImpl * ) prev ;
LONG bind_count = InterlockedDecrement ( & t - > baseTexture . bindCount ) ;
2006-12-19 23:26:39 +01:00
2009-09-28 10:05:02 +02:00
IWineD3DBaseTexture_Release ( prev ) ;
2010-01-27 20:19:42 +01:00
if ( ! texture & & stage < gl_info - > limits . texture_stages )
2009-09-28 10:05:02 +02:00
{
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( stage , WINED3DTSS_COLOROP ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_TEXTURESTAGE ( stage , WINED3DTSS_ALPHAOP ) ) ;
2006-12-19 23:00:58 +01:00
}
2005-07-13 16:15:54 +02:00
2009-09-28 10:05:02 +02:00
if ( bind_count & & t - > baseTexture . sampler = = stage )
{
unsigned int i ;
/* Search for other stages the texture is bound to. Shouldn't
* happen if applications bind textures to a single stage only . */
TRACE ( " Searching for other stages the texture is bound to. \n " ) ;
for ( i = 0 ; i < MAX_COMBINED_SAMPLERS ; + + i )
{
if ( This - > updateStateBlock - > textures [ i ] = = prev )
{
TRACE ( " Texture is also bound to stage %u. \n " , i ) ;
t - > baseTexture . sampler = i ;
2006-12-19 23:26:39 +01:00
break ;
}
}
}
2006-05-24 17:15:24 +02:00
}
2009-09-28 10:05:02 +02:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( stage ) ) ;
2006-12-19 23:26:39 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-18 12:42:29 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetTexture ( IWineD3DDevice * iface , DWORD Stage , IWineD3DBaseTexture * * ppTexture ) {
2005-01-18 12:42:29 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-06-25 22:46:01 +02:00
TRACE ( " (%p) : Stage %#x, ppTexture %p \n " , This , Stage , ppTexture ) ;
if ( Stage > = WINED3DVERTEXTEXTURESAMPLER0 & & Stage < = WINED3DVERTEXTEXTURESAMPLER3 ) {
Stage - = ( WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS ) ;
}
2005-08-22 11:13:49 +02:00
2008-01-15 08:06:37 +01:00
if ( Stage > = sizeof ( This - > stateBlock - > textures ) / sizeof ( This - > stateBlock - > textures [ 0 ] ) ) {
2008-01-24 14:03:10 +01:00
ERR ( " Current stage overflows textures array (stage %d) \n " , Stage ) ;
2008-01-15 08:06:37 +01:00
return WINED3D_OK ; /* Windows accepts overflowing this array ... we do not. */
}
2006-10-29 01:55:55 +02:00
* ppTexture = This - > stateBlock - > textures [ Stage ] ;
2006-11-30 13:33:29 +01:00
if ( * ppTexture )
IWineD3DBaseTexture_AddRef ( * ppTexture ) ;
2006-10-29 01:54:25 +02:00
2007-06-25 22:46:01 +02:00
TRACE ( " (%p) : Returning %p \n " , This , * ppTexture ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-18 12:42:29 +01:00
}
/*****
* Get Back Buffer
* * * * */
2009-12-16 19:55:58 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetBackBuffer ( IWineD3DDevice * iface , UINT swapchain_idx ,
UINT backbuffer_idx , WINED3DBACKBUFFER_TYPE backbuffer_type , IWineD3DSurface * * backbuffer )
{
IWineD3DSwapChain * swapchain ;
2005-06-23 13:05:24 +02:00
HRESULT hr ;
2009-12-16 19:55:58 +01:00
TRACE ( " iface %p, swapchain_idx %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p. \n " ,
iface , swapchain_idx , backbuffer_idx , backbuffer_type , backbuffer ) ;
2005-01-18 12:42:29 +01:00
2009-12-16 19:55:58 +01:00
hr = IWineD3DDeviceImpl_GetSwapChain ( iface , swapchain_idx , & swapchain ) ;
if ( FAILED ( hr ) )
{
WARN ( " Failed to get swapchain %u, hr %#x. \n " , swapchain_idx , hr ) ;
return hr ;
2005-01-18 12:42:29 +01:00
}
2009-12-16 19:55:58 +01:00
hr = IWineD3DSwapChain_GetBackBuffer ( swapchain , backbuffer_idx , backbuffer_type , backbuffer ) ;
IWineD3DSwapChain_Release ( swapchain ) ;
if ( FAILED ( hr ) )
{
WARN ( " Failed to get backbuffer %u, hr %#x. \n " , backbuffer_idx , hr ) ;
return hr ;
}
return WINED3D_OK ;
2005-01-18 12:42:29 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetDeviceCaps ( IWineD3DDevice * iface , WINED3DCAPS * pCaps ) {
2005-01-18 12:42:29 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
WARN ( " (%p) : stub, calling idirect3d for now \n " , This ) ;
2009-12-07 20:20:02 +01:00
return IWineD3D_GetDeviceCaps ( This - > wined3d , This - > adapter - > ordinal , This - > devType , pCaps ) ;
2005-01-18 12:42:29 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetDisplayMode ( IWineD3DDevice * iface , UINT iSwapChain , WINED3DDISPLAYMODE * pMode ) {
2005-01-18 12:42:29 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-06-23 13:05:24 +02:00
IWineD3DSwapChain * swapChain ;
HRESULT hr ;
2005-01-18 12:42:29 +01:00
2006-05-18 22:42:22 +02:00
if ( iSwapChain > 0 ) {
2008-01-23 22:39:56 +01:00
hr = IWineD3DDeviceImpl_GetSwapChain ( iface , iSwapChain , & swapChain ) ;
2006-05-18 22:42:22 +02:00
if ( hr = = WINED3D_OK ) {
hr = IWineD3DSwapChain_GetDisplayMode ( swapChain , pMode ) ;
2006-11-30 13:33:11 +01:00
IWineD3DSwapChain_Release ( swapChain ) ;
2006-05-18 22:42:22 +02:00
} else {
FIXME ( " (%p) Error getting display mode \n " , This ) ;
}
2005-08-22 11:13:49 +02:00
} else {
2006-05-18 22:42:22 +02:00
/* Don't read the real display mode,
but return the stored mode instead . X11 can ' t change the color
depth , and some apps are pretty angry if they SetDisplayMode from
24 to 16 bpp and find out that GetDisplayMode still returns 24 bpp
Also don ' t relay to the swapchain because with ddraw it ' s possible
that there isn ' t a swapchain at all */
pMode - > Width = This - > ddraw_width ;
pMode - > Height = This - > ddraw_height ;
pMode - > Format = This - > ddraw_format ;
pMode - > RefreshRate = 0 ;
hr = WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
2006-05-18 22:42:22 +02:00
2005-06-23 13:05:24 +02:00
return hr ;
2005-01-18 12:42:29 +01:00
}
2006-04-13 23:37:47 +02:00
2005-03-02 13:16:10 +01:00
/*****
* Stateblock related functions
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock ( IWineD3DDevice * iface ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-01-09 10:23:43 +01:00
IWineD3DStateBlock * stateblock ;
HRESULT hr ;
2007-02-14 17:46:54 +01:00
2007-08-19 20:47:10 +02:00
TRACE ( " (%p) \n " , This ) ;
2007-02-14 17:46:54 +01:00
2009-01-09 10:23:43 +01:00
if ( This - > isRecordingState ) return WINED3DERR_INVALIDCALL ;
2007-02-14 17:46:54 +01:00
2009-01-09 10:23:43 +01:00
hr = IWineD3DDeviceImpl_CreateStateBlock ( iface , WINED3DSBT_RECORDED , & stateblock , NULL ) ;
if ( FAILED ( hr ) ) return hr ;
2005-07-13 16:15:54 +02:00
2005-03-02 13:16:10 +01:00
IWineD3DStateBlock_Release ( ( IWineD3DStateBlock * ) This - > updateStateBlock ) ;
2009-01-09 10:23:43 +01:00
This - > updateStateBlock = ( IWineD3DStateBlockImpl * ) stateblock ;
2005-03-02 13:16:10 +01:00
This - > isRecordingState = TRUE ;
2005-07-13 16:15:54 +02:00
2009-01-09 10:23:43 +01:00
TRACE ( " (%p) recording stateblock %p \n " , This , stateblock ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock ( IWineD3DDevice * iface , IWineD3DStateBlock * * ppStateBlock ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-07-31 15:04:56 +02:00
IWineD3DStateBlockImpl * object = This - > updateStateBlock ;
2005-03-02 13:16:10 +01:00
if ( ! This - > isRecordingState ) {
2008-12-29 16:31:22 +01:00
WARN ( " (%p) not recording! returning error \n " , This ) ;
2005-03-02 13:16:10 +01:00
* ppStateBlock = NULL ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-03-02 13:16:10 +01:00
}
2009-09-30 10:49:13 +02:00
stateblock_init_contained_states ( object ) ;
2007-07-31 15:04:56 +02:00
* ppStateBlock = ( IWineD3DStateBlock * ) object ;
2005-03-02 13:16:10 +01:00
This - > isRecordingState = FALSE ;
2005-07-13 16:15:54 +02:00
This - > updateStateBlock = This - > stateBlock ;
2005-03-02 13:16:10 +01:00
IWineD3DStateBlock_AddRef ( ( IWineD3DStateBlock * ) This - > updateStateBlock ) ;
/* IWineD3DStateBlock_AddRef(*ppStateBlock); don't need to do this, since we should really just release UpdateStateBlock first */
TRACE ( " (%p) returning token (ptr to stateblock) of %p \n " , This , * ppStateBlock ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2004-11-28 16:04:41 +01:00
/*****
* Scene related functions
* * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_BeginScene ( IWineD3DDevice * iface ) {
2004-11-28 16:04:41 +01:00
/* At the moment we have no need for any functionality at the beginning
of a scene */
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-02-09 16:35:45 +01:00
TRACE ( " (%p) \n " , This ) ;
if ( This - > inScene ) {
TRACE ( " Already in Scene, returning WINED3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
This - > inScene = TRUE ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-28 16:04:41 +01:00
}
2009-10-28 11:00:11 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_EndScene ( IWineD3DDevice * iface )
{
2004-12-14 12:54:27 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-10-28 11:00:11 +01:00
struct wined3d_context * context ;
2004-12-14 12:54:27 +01:00
TRACE ( " (%p) \n " , This ) ;
2007-02-09 16:35:45 +01:00
if ( ! This - > inScene ) {
TRACE ( " Not in scene, returning WINED3DERR_INVALIDCALL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
2009-10-28 11:00:11 +01:00
context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2005-03-14 11:12:52 +01:00
/* We only have to do this if we need to read the, swapbuffers performs a flush for us */
2009-08-26 11:44:34 +02:00
wglFlush ( ) ;
2008-08-04 20:34:47 +02:00
/* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever
2009-10-28 11:00:11 +01:00
* fails . */
context_release ( context ) ;
2007-02-12 19:21:10 +01:00
2007-02-09 16:35:45 +01:00
This - > inScene = FALSE ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-14 12:54:27 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_Present ( IWineD3DDevice * iface ,
2009-12-21 23:17:26 +01:00
const RECT * pSourceRect , const RECT * pDestRect ,
HWND hDestWindowOverride , const RGNDATA * pDirtyRegion )
{
2005-06-23 13:05:24 +02:00
IWineD3DSwapChain * swapChain = NULL ;
int i ;
int swapchains = IWineD3DDeviceImpl_GetNumberOfSwapChains ( iface ) ;
2004-12-14 12:54:27 +01:00
2009-12-21 23:17:26 +01:00
TRACE ( " iface %p. \n " , iface ) ;
2004-12-14 12:54:27 +01:00
2005-07-13 16:15:54 +02:00
for ( i = 0 ; i < swapchains ; i + + ) {
2004-12-14 12:54:27 +01:00
2008-01-23 22:39:56 +01:00
IWineD3DDeviceImpl_GetSwapChain ( iface , i , & swapChain ) ;
2005-06-23 13:05:24 +02:00
TRACE ( " presentinng chain %d, %p \n " , i , swapChain ) ;
IWineD3DSwapChain_Present ( swapChain , pSourceRect , pDestRect , hDestWindowOverride , pDirtyRegion , 0 ) ;
2006-11-30 13:33:11 +01:00
IWineD3DSwapChain_Release ( swapChain ) ;
2004-12-14 12:54:27 +01:00
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-14 12:54:27 +01:00
}
2010-04-28 00:08:51 +02:00
static BOOL is_full_clear ( IWineD3DSurfaceImpl * target , const RECT * draw_rect , const RECT * clear_rect )
2010-03-16 19:02:18 +01:00
{
2010-04-28 00:08:50 +02:00
/* partial draw rect */
if ( draw_rect - > left | | draw_rect - > top
| | draw_rect - > right < target - > currentDesc . Width
| | draw_rect - > bottom < target - > currentDesc . Height )
2010-03-16 19:02:18 +01:00
return FALSE ;
/* partial clear rect */
2010-04-28 00:08:51 +02:00
if ( clear_rect & & ( clear_rect - > left > 0 | | clear_rect - > top > 0
| | clear_rect - > right < target - > currentDesc . Width
| | clear_rect - > bottom < target - > currentDesc . Height ) )
2010-03-16 19:02:18 +01:00
return FALSE ;
return TRUE ;
}
2007-12-20 08:32:11 +01:00
/* Not called from the VTable (internal subroutine) */
2010-03-16 19:02:18 +01:00
HRESULT IWineD3DDeviceImpl_ClearSurface ( IWineD3DDeviceImpl * This , IWineD3DSurfaceImpl * target , DWORD Count ,
const WINED3DRECT * pRects , DWORD Flags , WINED3DCOLOR Color , float Z , DWORD Stencil )
{
2010-04-28 00:08:51 +02:00
const RECT * clear_rect = ( Count > 0 & & pRects ) ? ( const RECT * ) pRects : NULL ;
2010-04-19 20:47:01 +02:00
IWineD3DSurfaceImpl * depth_stencil = This - > depth_stencil ;
2007-12-20 08:32:11 +01:00
GLbitfield glMask = 0 ;
unsigned int i ;
UINT drawable_width , drawable_height ;
2009-08-03 08:06:51 +02:00
struct wined3d_context * context ;
2010-04-28 00:08:50 +02:00
RECT draw_rect ;
device_get_draw_rect ( This , & draw_rect ) ;
2007-12-20 08:32:11 +01:00
/* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
* drawable . After the clear we ' ll mark the drawable up to date , so we have to make sure that this is true
* for the cleared parts , and the untouched parts .
*
* If we ' re clearing the whole target there is no need to copy it into the drawable , it will be overwritten
* anyway . If we ' re not clearing the color buffer we don ' t have to copy either since we ' re not going to set
* the drawable up to date . We have to check all settings that limit the clear area though . Do not bother
* checking all this if the dest surface is in the drawable anyway .
*/
2010-03-16 19:02:18 +01:00
if ( Flags & WINED3DCLEAR_TARGET & & ! ( target - > Flags & SFLAG_INDRAWABLE ) )
{
2010-04-28 00:08:50 +02:00
if ( ! is_full_clear ( target , & draw_rect , clear_rect ) )
2010-03-16 19:02:18 +01:00
IWineD3DSurface_LoadLocation ( ( IWineD3DSurface * ) target , SFLAG_INDRAWABLE , NULL ) ;
2007-12-20 08:32:11 +01:00
}
2010-04-21 22:02:32 +02:00
context = context_acquire ( This , target , CTXUSAGE_CLEAR ) ;
2010-04-12 12:08:06 +02:00
if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO )
{
2010-04-18 22:50:45 +02:00
if ( ! surface_is_offscreen ( target ) )
2010-04-12 12:08:06 +02:00
{
TRACE ( " Surface %p is onscreen \n " , target ) ;
ENTER_GL ( ) ;
context_bind_fbo ( context , GL_FRAMEBUFFER , NULL ) ;
2010-04-20 22:38:42 +02:00
context_set_draw_buffer ( context , surface_get_gl_buffer ( target ) ) ;
2010-04-12 12:08:06 +02:00
LEAVE_GL ( ) ;
}
else
{
TRACE ( " Surface %p is offscreen \n " , target ) ;
ENTER_GL ( ) ;
context_bind_fbo ( context , GL_FRAMEBUFFER , & context - > dst_fbo ) ;
2010-04-15 19:21:25 +02:00
context_attach_surface_fbo ( context , GL_FRAMEBUFFER , 0 , target ) ;
2010-04-16 12:41:02 +02:00
context_attach_depth_stencil_fbo ( context , GL_FRAMEBUFFER , depth_stencil , TRUE ) ;
2010-04-12 12:08:06 +02:00
LEAVE_GL ( ) ;
}
}
2010-03-17 21:59:54 +01:00
if ( ! context - > valid )
{
context_release ( context ) ;
WARN ( " Invalid context, skipping clear. \n " ) ;
return WINED3D_OK ;
}
2009-07-23 10:54:37 +02:00
2009-07-24 10:44:15 +02:00
target - > get_drawable_size ( context , & drawable_width , & drawable_height ) ;
2007-12-20 08:32:11 +01:00
ENTER_GL ( ) ;
/* Only set the values up once, as they are not changing */
2010-03-25 09:32:35 +01:00
if ( Flags & WINED3DCLEAR_STENCIL )
{
if ( context - > gl_info - > supported [ EXT_STENCIL_TWO_SIDE ] )
{
glDisable ( GL_STENCIL_TEST_TWO_SIDE_EXT ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_TWOSIDEDSTENCILMODE ) ) ;
}
2010-03-25 09:32:36 +01:00
glStencilMask ( ~ 0U ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_STENCILWRITEMASK ) ) ;
2007-12-20 08:32:11 +01:00
glClearStencil ( Stencil ) ;
checkGLcall ( " glClearStencil " ) ;
glMask = glMask | GL_STENCIL_BUFFER_BIT ;
}
2010-03-25 09:32:37 +01:00
if ( Flags & WINED3DCLEAR_ZBUFFER )
{
2009-08-06 08:12:19 +02:00
DWORD location = context - > render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN ;
2010-04-20 22:38:41 +02:00
if ( location = = SFLAG_DS_ONSCREEN & & depth_stencil ! = This - > onscreen_depth_stencil )
device_switch_onscreen_ds ( This , context , depth_stencil ) ;
2010-04-28 00:08:50 +02:00
if ( ! ( depth_stencil - > Flags & location ) & & ! is_full_clear ( depth_stencil , & draw_rect , clear_rect ) )
2010-04-18 22:50:43 +02:00
surface_load_ds_location ( depth_stencil , context , location ) ;
2010-04-21 00:35:05 +02:00
surface_modify_ds_location ( depth_stencil , location ) ;
2010-03-25 09:32:37 +01:00
2007-12-20 08:32:11 +01:00
glDepthMask ( GL_TRUE ) ;
2010-03-25 09:32:37 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_ZWRITEENABLE ) ) ;
2007-12-20 08:32:11 +01:00
glClearDepth ( Z ) ;
checkGLcall ( " glClearDepth " ) ;
glMask = glMask | GL_DEPTH_BUFFER_BIT ;
}
2010-03-25 09:32:38 +01:00
if ( Flags & WINED3DCLEAR_TARGET )
{
2010-04-21 00:35:05 +02:00
IWineD3DSurface_ModifyLocation ( ( IWineD3DSurface * ) target , SFLAG_INDRAWABLE , TRUE ) ;
2007-12-20 08:32:11 +01:00
glColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
2010-03-25 09:32:38 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE ) ) ;
2010-03-25 22:51:22 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE1 ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE2 ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE3 ) ) ;
2010-03-25 09:32:38 +01:00
glClearColor ( D3DCOLOR_R ( Color ) , D3DCOLOR_G ( Color ) , D3DCOLOR_B ( Color ) , D3DCOLOR_A ( Color ) ) ;
checkGLcall ( " glClearColor " ) ;
2007-12-20 08:32:11 +01:00
glMask = glMask | GL_COLOR_BUFFER_BIT ;
}
2010-04-28 00:08:50 +02:00
if ( ! clear_rect )
{
2009-08-06 08:12:19 +02:00
if ( context - > render_offscreen )
{
2010-04-28 00:08:50 +02:00
glScissor ( draw_rect . left , draw_rect . top ,
draw_rect . right - draw_rect . left , draw_rect . bottom - draw_rect . top ) ;
}
else
{
glScissor ( draw_rect . left , drawable_height - draw_rect . bottom ,
draw_rect . right - draw_rect . left , draw_rect . bottom - draw_rect . top ) ;
2007-12-20 08:32:11 +01:00
}
checkGLcall ( " glScissor " ) ;
glClear ( glMask ) ;
checkGLcall ( " glClear " ) ;
2010-04-28 00:08:50 +02:00
}
else
{
RECT current_rect ;
/* Now process each rect in turn. */
for ( i = 0 ; i < Count ; + + i )
{
2007-12-20 08:32:11 +01:00
/* Note gl uses lower left, width/height */
2010-04-28 00:08:51 +02:00
IntersectRect ( & current_rect , & draw_rect , & clear_rect [ i ] ) ;
2010-04-28 00:08:50 +02:00
TRACE ( " clear_rect[%u] %s, current_rect %s. \n " , i ,
2010-04-28 00:08:51 +02:00
wine_dbgstr_rect ( & clear_rect [ i ] ) ,
2010-04-28 00:08:50 +02:00
wine_dbgstr_rect ( & current_rect ) ) ;
2007-12-20 08:32:11 +01:00
/* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently.
* The rectangle is not cleared , no error is returned , but further rectanlges are
2010-04-28 00:08:50 +02:00
* still cleared if they are valid . */
if ( current_rect . left > current_rect . right | | current_rect . top > current_rect . bottom )
{
TRACE ( " Rectangle with negative dimensions, ignoring. \n " ) ;
2007-12-20 08:32:11 +01:00
continue ;
}
2009-08-06 08:12:19 +02:00
if ( context - > render_offscreen )
{
2010-04-28 00:08:50 +02:00
glScissor ( current_rect . left , current_rect . top ,
current_rect . right - current_rect . left , current_rect . bottom - current_rect . top ) ;
}
else
{
glScissor ( current_rect . left , drawable_height - current_rect . bottom ,
current_rect . right - current_rect . left , current_rect . bottom - current_rect . top ) ;
2007-12-20 08:32:11 +01:00
}
checkGLcall ( " glScissor " ) ;
glClear ( glMask ) ;
checkGLcall ( " glClear " ) ;
}
}
LEAVE_GL ( ) ;
2010-04-13 20:46:26 +02:00
if ( wined3d_settings . strict_draw_ordering | | ( ( target - > Flags & SFLAG_SWAPCHAIN )
2010-04-26 21:33:00 +02:00
& & ( ( IWineD3DSwapChainImpl * ) target - > container ) - > front_buffer = = target ) )
2010-04-13 20:46:26 +02:00
wglFlush ( ) ; /* Flush to ensure ordering across contexts. */
2008-08-31 16:05:26 +02:00
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2007-12-20 08:32:11 +01:00
return WINED3D_OK ;
}
2010-04-19 20:46:59 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_Clear ( IWineD3DDevice * iface , DWORD Count ,
const WINED3DRECT * pRects , DWORD Flags , WINED3DCOLOR Color , float Z , DWORD Stencil )
{
2004-12-14 12:54:27 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-06-04 18:12:31 +02:00
TRACE ( " (%p) Count (%d), pRects (%p), Flags (%x), Color (0x%08x), Z (%f), Stencil (%d) \n " , This ,
Count , pRects , Flags , Color , Z , Stencil ) ;
2004-12-14 12:54:27 +01:00
2010-04-19 20:47:01 +02:00
if ( Flags & ( WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL ) & & ! This - > depth_stencil )
{
2007-03-06 13:35:56 +01:00
WARN ( " Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL \n " ) ;
/* TODO: What about depth stencil buffers without stencil bits? */
return WINED3DERR_INVALIDCALL ;
}
2010-04-19 20:46:59 +02:00
return IWineD3DDeviceImpl_ClearSurface ( This , This - > render_targets [ 0 ] , Count , pRects , Flags , Color , Z , Stencil ) ;
2004-12-14 12:54:27 +01:00
}
2004-12-09 12:42:34 +01:00
/*****
* Drawing functions
* * * * */
2009-03-05 12:30:43 +01:00
static void WINAPI IWineD3DDeviceImpl_SetPrimitiveType ( IWineD3DDevice * iface ,
WINED3DPRIMITIVETYPE primitive_type )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " iface %p, primitive_type %s \n " , iface , debug_d3dprimitivetype ( primitive_type ) ) ;
This - > updateStateBlock - > changed . primitive_type = TRUE ;
This - > updateStateBlock - > gl_primitive_type = gl_primitive_type_from_d3d ( primitive_type ) ;
}
static void WINAPI IWineD3DDeviceImpl_GetPrimitiveType ( IWineD3DDevice * iface ,
WINED3DPRIMITIVETYPE * primitive_type )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " iface %p, primitive_type %p \n " , iface , primitive_type ) ;
* primitive_type = d3d_primitive_type_from_gl ( This - > stateBlock - > gl_primitive_type ) ;
TRACE ( " Returning %s \n " , debug_d3dprimitivetype ( * primitive_type ) ) ;
}
static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitive ( IWineD3DDevice * iface , UINT StartVertex , UINT vertex_count )
2009-03-05 12:30:42 +01:00
{
2004-12-09 12:42:34 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-05 12:30:43 +01:00
TRACE ( " (%p) : start %u, count %u \n " , This , StartVertex , vertex_count ) ;
2004-12-09 12:42:34 +01:00
2008-04-07 12:08:16 +02:00
if ( ! This - > stateBlock - > vertexDecl ) {
WARN ( " (%p) : Called without a valid vertex declaration set \n " , This ) ;
return WINED3DERR_INVALIDCALL ;
}
2007-03-10 00:44:46 +01:00
/* The index buffer is not needed here, but restore it, otherwise it is hell to keep track of */
if ( This - > stateBlock - > streamIsUP ) {
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_INDEXBUFFER ) ;
This - > stateBlock - > streamIsUP = FALSE ;
}
2007-01-06 18:19:55 +01:00
if ( This - > stateBlock - > loadBaseVertexIndex ! = 0 ) {
This - > stateBlock - > loadBaseVertexIndex = 0 ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_STREAMSRC ) ;
}
2007-01-02 21:07:39 +01:00
/* Account for the loading offset due to index buffers. Instead of reloading all sources correct it with the startvertex parameter */
2009-09-10 16:57:16 +02:00
drawPrimitive ( iface , vertex_count , StartVertex /* start_idx */ , 0 /* indxSize */ , NULL /* indxData */ ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2009-09-10 16:57:16 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive ( IWineD3DDevice * iface , UINT startIndex , UINT index_count )
2009-03-05 12:30:42 +01:00
{
2004-12-09 12:42:34 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
UINT idxStride = 2 ;
2009-04-06 16:46:12 +02:00
IWineD3DBuffer * pIB ;
2007-02-20 22:46:31 +01:00
GLuint vbo ;
2005-07-13 16:15:54 +02:00
2007-06-02 15:54:49 +02:00
pIB = This - > stateBlock - > pIndexData ;
if ( ! pIB ) {
/* D3D9 returns D3DERR_INVALIDCALL when DrawIndexedPrimitive is called
* without an index buffer set . ( The first time at least . . . )
* D3D8 simply dies , but I doubt it can do much harm to return
* D3DERR_INVALIDCALL there as well . */
2008-12-29 16:31:22 +01:00
WARN ( " (%p) : Called without a valid index buffer set, returning WINED3DERR_INVALIDCALL \n " , This ) ;
2007-06-02 15:54:49 +02:00
return WINED3DERR_INVALIDCALL ;
}
2008-04-07 12:08:16 +02:00
if ( ! This - > stateBlock - > vertexDecl ) {
WARN ( " (%p) : Called without a valid vertex declaration set \n " , This ) ;
return WINED3DERR_INVALIDCALL ;
}
2007-03-10 00:44:46 +01:00
if ( This - > stateBlock - > streamIsUP ) {
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_INDEXBUFFER ) ;
This - > stateBlock - > streamIsUP = FALSE ;
}
2009-04-06 13:38:56 +02:00
vbo = ( ( struct wined3d_buffer * ) pIB ) - > buffer_object ;
2004-12-09 12:42:34 +01:00
2009-09-10 16:57:16 +02:00
TRACE ( " (%p) : startIndex %u, index count %u. \n " , This , startIndex , index_count ) ;
2004-12-09 12:42:34 +01:00
2009-04-09 10:50:31 +02:00
if ( This - > stateBlock - > IndexFmt = = WINED3DFMT_R16_UINT ) {
2004-12-09 12:42:34 +01:00
idxStride = 2 ;
} else {
idxStride = 4 ;
}
2007-01-06 18:19:55 +01:00
if ( This - > stateBlock - > loadBaseVertexIndex ! = This - > stateBlock - > baseVertexIndex ) {
This - > stateBlock - > loadBaseVertexIndex = This - > stateBlock - > baseVertexIndex ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_STREAMSRC ) ;
}
2009-09-10 16:57:16 +02:00
drawPrimitive ( iface , index_count , startIndex , idxStride ,
vbo ? NULL : ( ( struct wined3d_buffer * ) pIB ) - > resource . allocatedMemory ) ;
2004-12-09 12:42:34 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2009-03-05 12:30:43 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP ( IWineD3DDevice * iface , UINT vertex_count ,
const void * pVertexStreamZeroData , UINT VertexStreamZeroStride )
2009-03-05 12:30:42 +01:00
{
2004-12-09 12:42:34 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-06 14:56:23 +01:00
IWineD3DBuffer * vb ;
2004-12-09 12:42:34 +01:00
2009-03-05 12:30:43 +01:00
TRACE ( " (%p) : vertex count %u, pVtxData %p, stride %u \n " ,
This , vertex_count , pVertexStreamZeroData , VertexStreamZeroStride ) ;
2004-12-09 12:42:34 +01:00
2008-04-07 12:08:16 +02:00
if ( ! This - > stateBlock - > vertexDecl ) {
WARN ( " (%p) : Called without a valid vertex declaration set \n " , This ) ;
return WINED3DERR_INVALIDCALL ;
}
2004-12-20 20:27:06 +01:00
/* Note in the following, it's not this type, but that's the purpose of streamIsUP */
2007-08-14 14:49:39 +02:00
vb = This - > stateBlock - > streamSource [ 0 ] ;
2009-03-06 14:56:23 +01:00
This - > stateBlock - > streamSource [ 0 ] = ( IWineD3DBuffer * ) pVertexStreamZeroData ;
if ( vb ) IWineD3DBuffer_Release ( vb ) ;
2007-04-09 01:55:27 +02:00
This - > stateBlock - > streamOffset [ 0 ] = 0 ;
2005-07-05 16:05:18 +02:00
This - > stateBlock - > streamStride [ 0 ] = VertexStreamZeroStride ;
2004-12-09 12:42:34 +01:00
This - > stateBlock - > streamIsUP = TRUE ;
2007-01-06 18:19:55 +01:00
This - > stateBlock - > loadBaseVertexIndex = 0 ;
2005-08-19 12:05:00 +02:00
2007-01-04 00:14:20 +01:00
/* TODO: Only mark dirty if drawing from a different UP address */
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_STREAMSRC ) ;
2009-09-10 16:57:16 +02:00
drawPrimitive ( iface , vertex_count , 0 /* start_idx */ , 0 /* indxSize*/ , NULL /* indxData */ ) ;
2006-05-10 19:57:49 +02:00
/* MSDN specifies stream zero settings must be set to NULL */
2005-07-05 16:05:18 +02:00
This - > stateBlock - > streamStride [ 0 ] = 0 ;
This - > stateBlock - > streamSource [ 0 ] = NULL ;
2004-12-09 12:42:34 +01:00
2007-01-04 00:14:20 +01:00
/* stream zero settings set to null at end, as per the msdn. No need to mark dirty here, the app has to set
* the new stream sources or use UP drawing again
*/
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2009-09-10 16:57:16 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP ( IWineD3DDevice * iface ,
UINT index_count , const void * pIndexData , WINED3DFORMAT IndexDataFormat ,
2009-03-05 12:30:42 +01:00
const void * pVertexStreamZeroData , UINT VertexStreamZeroStride )
{
2004-12-09 12:42:34 +01:00
int idxStride ;
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-03-06 14:56:23 +01:00
IWineD3DBuffer * vb ;
2009-04-06 16:46:12 +02:00
IWineD3DBuffer * ib ;
2004-12-09 12:42:34 +01:00
2009-09-10 16:57:16 +02:00
TRACE ( " (%p) : index count %u, pidxdata %p, IdxFmt %u, pVtxdata %p, stride=%u. \n " ,
This , index_count , pIndexData , IndexDataFormat , pVertexStreamZeroData , VertexStreamZeroStride ) ;
2004-12-09 12:42:34 +01:00
2008-04-07 12:08:16 +02:00
if ( ! This - > stateBlock - > vertexDecl ) {
WARN ( " (%p) : Called without a valid vertex declaration set \n " , This ) ;
return WINED3DERR_INVALIDCALL ;
}
2009-02-19 16:59:42 +01:00
if ( IndexDataFormat = = WINED3DFMT_R16_UINT ) {
2004-12-09 12:42:34 +01:00
idxStride = 2 ;
} else {
idxStride = 4 ;
}
2004-12-20 20:27:06 +01:00
/* Note in the following, it's not this type, but that's the purpose of streamIsUP */
2007-08-14 14:49:39 +02:00
vb = This - > stateBlock - > streamSource [ 0 ] ;
2009-03-06 14:56:23 +01:00
This - > stateBlock - > streamSource [ 0 ] = ( IWineD3DBuffer * ) pVertexStreamZeroData ;
if ( vb ) IWineD3DBuffer_Release ( vb ) ;
2004-12-09 12:42:34 +01:00
This - > stateBlock - > streamIsUP = TRUE ;
2007-04-09 01:55:27 +02:00
This - > stateBlock - > streamOffset [ 0 ] = 0 ;
2005-07-05 16:05:18 +02:00
This - > stateBlock - > streamStride [ 0 ] = VertexStreamZeroStride ;
2004-12-09 12:42:34 +01:00
2007-01-02 21:07:39 +01:00
/* Set to 0 as per msdn. Do it now due to the stream source loading during drawPrimitive */
This - > stateBlock - > baseVertexIndex = 0 ;
2007-01-06 18:19:55 +01:00
This - > stateBlock - > loadBaseVertexIndex = 0 ;
/* Mark the state dirty until we have nicer tracking of the stream source pointers */
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VDECL ) ;
2007-02-19 15:25:32 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_INDEXBUFFER ) ;
2007-01-02 00:35:07 +01:00
2009-09-10 16:57:16 +02:00
drawPrimitive ( iface , index_count , 0 /* start_idx */ , idxStride , pIndexData ) ;
2004-12-09 12:42:34 +01:00
2006-05-10 19:57:49 +02:00
/* MSDN specifies stream zero settings and index buffer must be set to NULL */
2005-07-05 16:05:18 +02:00
This - > stateBlock - > streamSource [ 0 ] = NULL ;
This - > stateBlock - > streamStride [ 0 ] = 0 ;
2007-08-14 14:46:38 +02:00
ib = This - > stateBlock - > pIndexData ;
if ( ib ) {
2009-04-06 16:46:12 +02:00
IWineD3DBuffer_Release ( ib ) ;
2007-08-14 14:46:38 +02:00
This - > stateBlock - > pIndexData = NULL ;
}
2007-01-06 18:19:55 +01:00
/* No need to mark the stream source state dirty here. Either the app calls UP drawing again, or it has to call
* SetStreamSource to specify a vertex buffer
*/
2004-12-09 12:42:34 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-09 12:42:34 +01:00
}
2008-12-01 15:32:15 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided ( IWineD3DDevice * iface ,
2009-03-05 12:30:43 +01:00
UINT vertex_count , const WineDirect3DVertexStridedData * DrawPrimStrideData )
2008-12-01 15:32:15 +01:00
{
2007-01-02 00:35:07 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-05-06 16:58:57 +02:00
2007-01-02 21:07:39 +01:00
/* Mark the state dirty until we have nicer tracking
* its fine to change baseVertexIndex because that call is only called by ddraw which does not need
* that value .
*/
2007-01-02 00:35:07 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VDECL ) ;
2007-02-19 15:25:32 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_INDEXBUFFER ) ;
2007-01-02 21:07:39 +01:00
This - > stateBlock - > baseVertexIndex = 0 ;
2007-01-02 21:13:28 +01:00
This - > up_strided = DrawPrimStrideData ;
2009-09-10 16:57:16 +02:00
drawPrimitive ( iface , vertex_count , 0 , 0 , NULL ) ;
2007-01-02 21:13:28 +01:00
This - > up_strided = NULL ;
2006-05-06 16:58:57 +02:00
return WINED3D_OK ;
}
2007-07-27 14:39:55 +02:00
2008-12-01 15:32:15 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided ( IWineD3DDevice * iface ,
2009-03-05 12:30:43 +01:00
UINT vertex_count , const WineDirect3DVertexStridedData * DrawPrimStrideData ,
2009-03-05 12:30:42 +01:00
UINT NumVertices , const void * pIndexData , WINED3DFORMAT IndexDataFormat )
2008-12-01 15:32:15 +01:00
{
2007-07-27 14:39:55 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-02-19 16:59:42 +01:00
DWORD idxSize = ( IndexDataFormat = = WINED3DFMT_R32_UINT ? 4 : 2 ) ;
2007-07-27 14:39:55 +02:00
/* Mark the state dirty until we have nicer tracking
* its fine to change baseVertexIndex because that call is only called by ddraw which does not need
* that value .
*/
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VDECL ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_INDEXBUFFER ) ;
This - > stateBlock - > streamIsUP = TRUE ;
This - > stateBlock - > baseVertexIndex = 0 ;
This - > up_strided = DrawPrimStrideData ;
2009-12-07 20:19:59 +01:00
drawPrimitive ( iface , vertex_count , 0 /* start_idx */ , idxSize , pIndexData ) ;
2007-07-27 14:39:55 +02:00
This - > up_strided = NULL ;
return WINED3D_OK ;
}
2009-12-21 23:17:26 +01:00
/* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */
static HRESULT IWineD3DDeviceImpl_UpdateVolume ( IWineD3DDevice * iface ,
IWineD3DVolume * pSourceVolume , IWineD3DVolume * pDestinationVolume )
{
2007-09-01 01:54:15 +02:00
WINED3DLOCKED_BOX src ;
WINED3DLOCKED_BOX dst ;
HRESULT hr ;
2009-12-21 23:17:26 +01:00
TRACE ( " iface %p, src_volume %p, dst_volume %p. \n " ,
iface , pSourceVolume , pDestinationVolume ) ;
2007-09-01 01:54:15 +02:00
/* TODO: Implement direct loading into the gl volume instead of using memcpy and
* dirtification to improve loading performance .
*/
hr = IWineD3DVolume_LockBox ( pSourceVolume , & src , NULL , WINED3DLOCK_READONLY ) ;
if ( FAILED ( hr ) ) return hr ;
hr = IWineD3DVolume_LockBox ( pDestinationVolume , & dst , NULL , WINED3DLOCK_DISCARD ) ;
if ( FAILED ( hr ) ) {
IWineD3DVolume_UnlockBox ( pSourceVolume ) ;
return hr ;
}
memcpy ( dst . pBits , src . pBits , ( ( IWineD3DVolumeImpl * ) pDestinationVolume ) - > resource . size ) ;
hr = IWineD3DVolume_UnlockBox ( pDestinationVolume ) ;
if ( FAILED ( hr ) ) {
IWineD3DVolume_UnlockBox ( pSourceVolume ) ;
} else {
hr = IWineD3DVolume_UnlockBox ( pSourceVolume ) ;
}
return hr ;
}
2007-07-27 14:39:55 +02:00
2009-10-19 10:12:19 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_UpdateTexture ( IWineD3DDevice * iface ,
IWineD3DBaseTexture * src_texture , IWineD3DBaseTexture * dst_texture )
{
unsigned int level_count , i ;
WINED3DRESOURCETYPE type ;
HRESULT hr ;
2005-07-12 19:02:47 +02:00
2009-10-19 10:12:19 +02:00
TRACE ( " iface %p, src_texture %p, dst_texture %p. \n " , iface , src_texture , dst_texture ) ;
2005-07-12 19:02:47 +02:00
2009-10-19 10:12:19 +02:00
/* Verify that the source and destination textures are non-NULL. */
if ( ! src_texture | | ! dst_texture )
{
WARN ( " Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL. \n " ) ;
return WINED3DERR_INVALIDCALL ;
2005-11-04 13:39:17 +01:00
}
2005-07-12 19:02:47 +02:00
2009-10-19 10:12:19 +02:00
if ( src_texture = = dst_texture )
{
WARN ( " Source and destination are the same object, returning WINED3DERR_INVALIDCALL. \n " ) ;
return WINED3DERR_INVALIDCALL ;
2005-07-12 19:02:47 +02:00
}
2009-10-19 10:12:19 +02:00
/* Verify that the source and destination textures are the same type. */
type = IWineD3DBaseTexture_GetType ( src_texture ) ;
if ( IWineD3DBaseTexture_GetType ( dst_texture ) ! = type )
{
WARN ( " Source and destination have different types, returning WINED3DERR_INVALIDCALL. \n " ) ;
return WINED3DERR_INVALIDCALL ;
2005-11-04 13:39:17 +01:00
}
2005-07-12 19:02:47 +02:00
2009-10-19 10:12:19 +02:00
/* Check that both textures have the identical numbers of levels. */
level_count = IWineD3DBaseTexture_GetLevelCount ( src_texture ) ;
if ( IWineD3DBaseTexture_GetLevelCount ( dst_texture ) ! = level_count )
{
WARN ( " Source and destination have different level counts, returning WINED3DERR_INVALIDCALL. \n " ) ;
return WINED3DERR_INVALIDCALL ;
2005-07-12 19:02:47 +02:00
}
2005-11-04 13:39:17 +01:00
2009-10-19 10:12:19 +02:00
/* Make sure that the destination texture is loaded. */
( ( IWineD3DBaseTextureImpl * ) dst_texture ) - > baseTexture . internal_preload ( dst_texture , SRGB_RGB ) ;
2005-11-04 13:39:17 +01:00
2009-10-19 10:12:19 +02:00
/* Update every surface level of the texture. */
switch ( type )
{
2006-03-09 23:21:16 +01:00
case WINED3DRTYPE_TEXTURE :
2009-10-19 10:12:19 +02:00
{
IWineD3DSurface * src_surface ;
IWineD3DSurface * dst_surface ;
for ( i = 0 ; i < level_count ; + + i )
2005-11-04 13:39:17 +01:00
{
2009-10-19 10:12:19 +02:00
IWineD3DTexture_GetSurfaceLevel ( ( IWineD3DTexture * ) src_texture , i , & src_surface ) ;
IWineD3DTexture_GetSurfaceLevel ( ( IWineD3DTexture * ) dst_texture , i , & dst_surface ) ;
hr = IWineD3DDevice_UpdateSurface ( iface , src_surface , NULL , dst_surface , NULL ) ;
IWineD3DSurface_Release ( dst_surface ) ;
IWineD3DSurface_Release ( src_surface ) ;
if ( FAILED ( hr ) )
{
WARN ( " IWineD3DDevice_UpdateSurface failed, hr %#x. \n " , hr ) ;
return hr ;
2005-11-04 13:39:17 +01:00
}
}
break ;
2009-10-19 10:12:19 +02:00
}
2006-03-09 23:21:16 +01:00
case WINED3DRTYPE_CUBETEXTURE :
2009-10-19 10:12:19 +02:00
{
IWineD3DSurface * src_surface ;
IWineD3DSurface * dst_surface ;
WINED3DCUBEMAP_FACES face ;
for ( i = 0 ; i < level_count ; + + i )
2005-11-04 13:39:17 +01:00
{
2009-10-19 10:12:19 +02:00
/* Update each cube face. */
for ( face = WINED3DCUBEMAP_FACE_POSITIVE_X ; face < = WINED3DCUBEMAP_FACE_NEGATIVE_Z ; + + face )
{
hr = IWineD3DCubeTexture_GetCubeMapSurface ( ( IWineD3DCubeTexture * ) src_texture ,
face , i , & src_surface ) ;
if ( FAILED ( hr ) ) ERR ( " Failed to get src cube surface face %u, level %u, hr %#x. \n " , face , i , hr ) ;
hr = IWineD3DCubeTexture_GetCubeMapSurface ( ( IWineD3DCubeTexture * ) dst_texture ,
face , i , & dst_surface ) ;
if ( FAILED ( hr ) ) ERR ( " Failed to get dst cube surface face %u, level %u, hr %#x. \n " , face , i , hr ) ;
hr = IWineD3DDevice_UpdateSurface ( iface , src_surface , NULL , dst_surface , NULL ) ;
IWineD3DSurface_Release ( dst_surface ) ;
IWineD3DSurface_Release ( src_surface ) ;
if ( FAILED ( hr ) )
{
WARN ( " IWineD3DDevice_UpdateSurface failed, hr %#x. \n " , hr ) ;
return hr ;
2005-11-04 13:39:17 +01:00
}
}
}
break ;
2009-10-19 10:12:19 +02:00
}
2007-09-01 01:54:15 +02:00
2006-03-09 23:21:16 +01:00
case WINED3DRTYPE_VOLUMETEXTURE :
2009-10-19 10:12:19 +02:00
{
IWineD3DVolume * src_volume ;
IWineD3DVolume * dst_volume ;
for ( i = 0 ; i < level_count ; + + i )
2005-11-04 13:39:17 +01:00
{
2009-10-19 10:12:19 +02:00
IWineD3DVolumeTexture_GetVolumeLevel ( ( IWineD3DVolumeTexture * ) src_texture , i , & src_volume ) ;
IWineD3DVolumeTexture_GetVolumeLevel ( ( IWineD3DVolumeTexture * ) dst_texture , i , & dst_volume ) ;
hr = IWineD3DDeviceImpl_UpdateVolume ( iface , src_volume , dst_volume ) ;
IWineD3DVolume_Release ( dst_volume ) ;
IWineD3DVolume_Release ( src_volume ) ;
if ( FAILED ( hr ) )
{
WARN ( " IWineD3DDeviceImpl_UpdateVolume failed, hr %#x. \n " , hr ) ;
return hr ;
2005-11-04 13:39:17 +01:00
}
}
break ;
2009-10-19 10:12:19 +02:00
}
2007-09-01 01:54:15 +02:00
2005-11-04 13:39:17 +01:00
default :
2009-10-19 10:12:19 +02:00
FIXME ( " Unsupported texture type %#x. \n " , type ) ;
return WINED3DERR_INVALIDCALL ;
2005-07-12 19:02:47 +02:00
}
2009-10-19 10:12:19 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-26 21:54:00 +01:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetFrontBufferData ( IWineD3DDevice * iface , UINT iSwapChain , IWineD3DSurface * pDestSurface ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChain * swapChain ;
HRESULT hr ;
2008-01-23 22:39:56 +01:00
hr = IWineD3DDeviceImpl_GetSwapChain ( iface , iSwapChain , & swapChain ) ;
2006-04-07 12:51:12 +02:00
if ( hr = = WINED3D_OK ) {
2005-06-23 13:05:24 +02:00
hr = IWineD3DSwapChain_GetFrontBufferData ( swapChain , pDestSurface ) ;
2006-11-30 13:33:11 +01:00
IWineD3DSwapChain_Release ( swapChain ) ;
2005-06-23 13:05:24 +02:00
}
return hr ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_ValidateDevice ( IWineD3DDevice * iface , DWORD * pNumPasses ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2008-08-21 15:10:46 +02:00
IWineD3DBaseTextureImpl * texture ;
DWORD i ;
2008-09-05 13:14:47 +02:00
TRACE ( " (%p) : %p \n " , This , pNumPasses ) ;
2008-08-21 15:10:46 +02:00
for ( i = 0 ; i < MAX_COMBINED_SAMPLERS ; i + + ) {
if ( This - > stateBlock - > samplerState [ i ] [ WINED3DSAMP_MINFILTER ] = = WINED3DTEXF_NONE ) {
WARN ( " Sampler state %u has minfilter D3DTEXF_NONE, returning D3DERR_UNSUPPORTEDTEXTUREFILTER \n " , i ) ;
return WINED3DERR_UNSUPPORTEDTEXTUREFILTER ;
}
if ( This - > stateBlock - > samplerState [ i ] [ WINED3DSAMP_MAGFILTER ] = = WINED3DTEXF_NONE ) {
WARN ( " Sampler state %u has magfilter D3DTEXF_NONE, returning D3DERR_UNSUPPORTEDTEXTUREFILTER \n " , i ) ;
return WINED3DERR_UNSUPPORTEDTEXTUREFILTER ;
}
texture = ( IWineD3DBaseTextureImpl * ) This - > stateBlock - > textures [ i ] ;
2009-03-12 09:53:15 +01:00
if ( ! texture | | texture - > resource . format_desc - > Flags & WINED3DFMT_FLAG_FILTERING ) continue ;
2008-08-21 15:10:46 +02:00
if ( This - > stateBlock - > samplerState [ i ] [ WINED3DSAMP_MAGFILTER ] ! = WINED3DTEXF_POINT ) {
WARN ( " Non-filterable texture and mag filter enabled on samper %u, returning E_FAIL \n " , i ) ;
return E_FAIL ;
}
if ( This - > stateBlock - > samplerState [ i ] [ WINED3DSAMP_MINFILTER ] ! = WINED3DTEXF_POINT ) {
WARN ( " Non-filterable texture and min filter enabled on samper %u, returning E_FAIL \n " , i ) ;
return E_FAIL ;
}
if ( This - > stateBlock - > samplerState [ i ] [ WINED3DSAMP_MIPFILTER ] ! = WINED3DTEXF_NONE & &
This - > stateBlock - > samplerState [ i ] [ WINED3DSAMP_MIPFILTER ] ! = WINED3DTEXF_POINT /* sic! */ ) {
WARN ( " Non-filterable texture and mip filter enabled on samper %u, returning E_FAIL \n " , i ) ;
return E_FAIL ;
}
}
2005-03-02 13:16:10 +01:00
/* return a sensible default */
* pNumPasses = 1 ;
2008-08-21 15:10:46 +02:00
TRACE ( " returning D3D_OK \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-27 11:40:57 +01:00
2008-04-02 23:12:16 +02:00
static void dirtify_p8_texture_samplers ( IWineD3DDeviceImpl * device )
{
int i ;
2009-09-25 13:31:49 +02:00
for ( i = 0 ; i < MAX_COMBINED_SAMPLERS ; + + i )
{
IWineD3DBaseTextureImpl * texture = ( IWineD3DBaseTextureImpl * ) device - > stateBlock - > textures [ i ] ;
if ( texture & & ( texture - > resource . format_desc - > format = = WINED3DFMT_P8_UINT
| | texture - > resource . format_desc - > format = = WINED3DFMT_P8_UINT_A8_UNORM ) )
{
IWineD3DDeviceImpl_MarkStateDirty ( device , STATE_SAMPLER ( i ) ) ;
2008-04-02 23:12:16 +02:00
}
2009-09-25 13:31:49 +02:00
}
2008-04-02 23:12:16 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetPaletteEntries ( IWineD3DDevice * iface , UINT PaletteNumber , CONST PALETTEENTRY * pEntries ) {
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-08-11 12:57:20 +02:00
int j ;
2008-03-26 23:23:04 +01:00
UINT NewSize ;
PALETTEENTRY * * palettes ;
2005-08-11 12:57:20 +02:00
TRACE ( " (%p) : PaletteNumber %u \n " , This , PaletteNumber ) ;
2008-03-26 23:23:04 +01:00
2008-01-01 14:25:28 +01:00
if ( PaletteNumber > = MAX_PALETTES ) {
2008-03-26 23:23:04 +01:00
ERR ( " (%p) : (%u) Out of range 0-%u, returning Invalid Call \n " , This , PaletteNumber , MAX_PALETTES ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-08-11 12:57:20 +02:00
}
2008-03-26 23:23:04 +01:00
if ( PaletteNumber > = This - > NumberOfPalettes ) {
NewSize = This - > NumberOfPalettes ;
do {
NewSize * = 2 ;
} while ( PaletteNumber > = NewSize ) ;
palettes = HeapReAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , This - > palettes , sizeof ( PALETTEENTRY * ) * NewSize ) ;
if ( ! palettes ) {
ERR ( " Out of memory! \n " ) ;
return E_OUTOFMEMORY ;
}
This - > palettes = palettes ;
This - > NumberOfPalettes = NewSize ;
}
if ( ! This - > palettes [ PaletteNumber ] ) {
This - > palettes [ PaletteNumber ] = HeapAlloc ( GetProcessHeap ( ) , 0 , sizeof ( PALETTEENTRY ) * 256 ) ;
if ( ! This - > palettes [ PaletteNumber ] ) {
ERR ( " Out of memory! \n " ) ;
return E_OUTOFMEMORY ;
}
}
2005-08-11 12:57:20 +02:00
for ( j = 0 ; j < 256 ; + + j ) {
This - > palettes [ PaletteNumber ] [ j ] . peRed = pEntries [ j ] . peRed ;
This - > palettes [ PaletteNumber ] [ j ] . peGreen = pEntries [ j ] . peGreen ;
This - > palettes [ PaletteNumber ] [ j ] . peBlue = pEntries [ j ] . peBlue ;
This - > palettes [ PaletteNumber ] [ j ] . peFlags = pEntries [ j ] . peFlags ;
}
2008-04-02 23:12:16 +02:00
if ( PaletteNumber = = This - > currentPalette ) dirtify_p8_texture_samplers ( This ) ;
2005-08-11 12:57:20 +02:00
TRACE ( " (%p) : returning \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-27 11:40:57 +01:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetPaletteEntries ( IWineD3DDevice * iface , UINT PaletteNumber , PALETTEENTRY * pEntries ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-08-11 12:57:20 +02:00
int j ;
TRACE ( " (%p) : PaletteNumber %u \n " , This , PaletteNumber ) ;
2008-03-26 23:23:04 +01:00
if ( PaletteNumber > = This - > NumberOfPalettes | | ! This - > palettes [ PaletteNumber ] ) {
/* What happens in such situation isn't documented; Native seems to silently abort
on such conditions . Return Invalid Call . */
2008-04-07 13:01:02 +02:00
ERR ( " (%p) : (%u) Nonexistent palette. NumberOfPalettes %u \n " , This , PaletteNumber , This - > NumberOfPalettes ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-08-11 12:57:20 +02:00
}
for ( j = 0 ; j < 256 ; + + j ) {
pEntries [ j ] . peRed = This - > palettes [ PaletteNumber ] [ j ] . peRed ;
pEntries [ j ] . peGreen = This - > palettes [ PaletteNumber ] [ j ] . peGreen ;
pEntries [ j ] . peBlue = This - > palettes [ PaletteNumber ] [ j ] . peBlue ;
pEntries [ j ] . peFlags = This - > palettes [ PaletteNumber ] [ j ] . peFlags ;
}
TRACE ( " (%p) : returning \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-26 21:54:00 +01:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetCurrentTexturePalette ( IWineD3DDevice * iface , UINT PaletteNumber ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-08-11 12:57:20 +02:00
TRACE ( " (%p) : PaletteNumber %u \n " , This , PaletteNumber ) ;
2008-03-26 23:23:04 +01:00
/* Native appears to silently abort on attempt to make an uninitialized palette current and render.
( tested with reference rasterizer ) . Return Invalid Call . */
if ( PaletteNumber > = This - > NumberOfPalettes | | ! This - > palettes [ PaletteNumber ] ) {
2008-04-07 13:01:02 +02:00
ERR ( " (%p) : (%u) Nonexistent palette. NumberOfPalettes %u \n " , This , PaletteNumber , This - > NumberOfPalettes ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-08-11 12:57:20 +02:00
}
/*TODO: stateblocks */
2008-04-02 23:12:16 +02:00
if ( This - > currentPalette ! = PaletteNumber ) {
This - > currentPalette = PaletteNumber ;
dirtify_p8_texture_samplers ( This ) ;
}
2005-08-11 12:57:20 +02:00
TRACE ( " (%p) : returning \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-26 21:54:00 +01:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetCurrentTexturePalette ( IWineD3DDevice * iface , UINT * PaletteNumber ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-08-11 12:57:20 +02:00
if ( PaletteNumber = = NULL ) {
WARN ( " (%p) : returning Invalid Call \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-08-11 12:57:20 +02:00
}
/*TODO: stateblocks */
* PaletteNumber = This - > currentPalette ;
TRACE ( " (%p) : returning %u \n " , This , * PaletteNumber ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-26 21:54:00 +01:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetSoftwareVertexProcessing ( IWineD3DDevice * iface , BOOL bSoftware ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2008-12-01 15:32:14 +01:00
static BOOL warned ;
if ( ! warned )
{
2005-08-11 12:31:40 +02:00
FIXME ( " (%p) : stub \n " , This ) ;
2008-12-01 15:32:14 +01:00
warned = TRUE ;
2005-08-11 12:31:40 +02:00
}
2005-10-29 12:30:36 +02:00
This - > softwareVertexProcessing = bSoftware ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-26 21:54:00 +01:00
}
2006-06-10 13:15:32 +02:00
static BOOL WINAPI IWineD3DDeviceImpl_GetSoftwareVertexProcessing ( IWineD3DDevice * iface ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2008-12-01 15:32:14 +01:00
static BOOL warned ;
if ( ! warned )
{
2005-08-11 12:31:40 +02:00
FIXME ( " (%p) : stub \n " , This ) ;
2008-12-01 15:32:14 +01:00
warned = TRUE ;
2005-08-11 12:31:40 +02:00
}
2005-10-29 12:30:36 +02:00
return This - > softwareVertexProcessing ;
2005-03-02 13:16:10 +01:00
}
2009-12-20 20:41:37 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetRasterStatus ( IWineD3DDevice * iface ,
UINT swapchain_idx , WINED3DRASTER_STATUS * raster_status )
{
IWineD3DSwapChain * swapchain ;
2005-08-27 11:58:53 +02:00
HRESULT hr ;
2005-07-13 16:15:54 +02:00
2009-12-20 20:41:37 +01:00
TRACE ( " iface %p, swapchain_idx %u, raster_status %p. \n " ,
iface , swapchain_idx , raster_status ) ;
2005-08-27 11:58:53 +02:00
2009-12-20 20:41:37 +01:00
hr = IWineD3DDeviceImpl_GetSwapChain ( iface , swapchain_idx , & swapchain ) ;
if ( FAILED ( hr ) )
{
WARN ( " Failed to get swapchain %u, hr %#x. \n " , swapchain_idx , hr ) ;
return hr ;
2005-08-27 11:58:53 +02:00
}
2005-03-02 13:16:10 +01:00
2009-12-20 20:41:37 +01:00
hr = IWineD3DSwapChain_GetRasterStatus ( swapchain , raster_status ) ;
IWineD3DSwapChain_Release ( swapchain ) ;
if ( FAILED ( hr ) )
{
WARN ( " Failed to get raster status, hr %#x. \n " , hr ) ;
return hr ;
}
return WINED3D_OK ;
}
2005-03-02 13:16:10 +01:00
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetNPatchMode ( IWineD3DDevice * iface , float nSegments )
{
2008-12-01 15:32:14 +01:00
static BOOL warned ;
2005-07-13 16:15:54 +02:00
if ( nSegments ! = 0.0f ) {
2008-12-01 15:32:14 +01:00
if ( ! warned )
{
2009-12-21 23:17:26 +01:00
FIXME ( " iface %p, nSegments %.8e stub! \n " , iface , nSegments ) ;
2008-12-01 15:32:14 +01:00
warned = TRUE ;
2005-03-02 13:16:10 +01:00
}
2005-01-26 21:54:00 +01:00
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-26 21:54:00 +01:00
}
2005-03-02 13:16:10 +01:00
2009-12-21 23:17:26 +01:00
static float WINAPI IWineD3DDeviceImpl_GetNPatchMode ( IWineD3DDevice * iface )
{
2008-12-01 15:32:14 +01:00
static BOOL warned ;
if ( ! warned )
{
2009-12-21 23:17:26 +01:00
FIXME ( " iface %p stub! \n " , iface ) ;
2008-12-01 15:32:14 +01:00
warned = TRUE ;
2005-03-02 13:16:10 +01:00
}
return 0.0f ;
}
2005-01-26 21:54:00 +01:00
2010-03-31 11:28:56 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface ( IWineD3DDevice * iface ,
IWineD3DSurface * src_surface , const RECT * src_rect ,
IWineD3DSurface * dst_surface , const POINT * dst_point )
{
IWineD3DSurfaceImpl * src_impl = ( IWineD3DSurfaceImpl * ) src_surface ;
IWineD3DSurfaceImpl * dst_impl = ( IWineD3DSurfaceImpl * ) dst_surface ;
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2010-03-30 11:24:48 +02:00
const struct wined3d_format_desc * src_format ;
const struct wined3d_format_desc * dst_format ;
2009-10-28 11:00:11 +01:00
struct wined3d_context * context ;
2010-03-30 11:24:47 +02:00
const unsigned char * data ;
2010-03-31 11:28:56 +02:00
UINT update_w , update_h ;
2010-03-31 11:28:58 +02:00
CONVERT_TYPES convert ;
2010-03-31 11:28:56 +02:00
UINT src_w , src_h ;
UINT dst_x , dst_y ;
DWORD sampler ;
2010-04-08 22:49:45 +02:00
struct wined3d_format_desc dummy_desc ;
2005-07-12 19:02:47 +02:00
2010-04-26 11:02:33 +02:00
TRACE ( " iface %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s. \n " ,
2010-03-31 11:28:56 +02:00
iface , src_surface , wine_dbgstr_rect ( src_rect ) ,
dst_surface , wine_dbgstr_point ( dst_point ) ) ;
2005-07-12 19:02:47 +02:00
2010-03-31 11:28:57 +02:00
if ( src_impl - > resource . pool ! = WINED3DPOOL_SYSTEMMEM | | dst_impl - > resource . pool ! = WINED3DPOOL_DEFAULT )
2010-03-31 11:28:56 +02:00
{
WARN ( " source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL \n " ,
src_surface , dst_surface ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-07-12 19:02:47 +02:00
}
2005-11-04 12:13:45 +01:00
2010-03-31 11:28:56 +02:00
src_format = src_impl - > resource . format_desc ;
2010-03-30 11:24:48 +02:00
dst_format = dst_impl - > resource . format_desc ;
if ( src_format - > format ! = dst_format - > format )
2010-03-30 11:24:45 +02:00
{
WARN ( " Source and destination surfaces should have the same format. \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
2010-03-31 11:28:56 +02:00
dst_x = dst_point ? dst_point - > x : 0 ;
dst_y = dst_point ? dst_point - > y : 0 ;
/* This call loads the OpenGL surface directly, instead of copying the
* surface to the destination ' s sysmem copy . If surface conversion is
* needed , use BltFast instead to copy in sysmem and use regular surface
* loading . */
2010-04-08 22:49:46 +02:00
d3dfmt_get_conv ( dst_impl , FALSE , TRUE , & dummy_desc , & convert ) ;
2010-03-31 11:28:56 +02:00
if ( convert ! = NO_CONVERSION )
return IWineD3DSurface_BltFast ( dst_surface , dst_x , dst_y , src_surface , src_rect , 0 ) ;
2007-08-11 20:02:01 +02:00
2009-10-28 11:00:11 +01:00
context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2007-03-17 23:00:39 +01:00
2008-12-16 13:18:49 +01:00
ENTER_GL ( ) ;
GL_EXTCALL ( glActiveTextureARB ( GL_TEXTURE0_ARB ) ) ;
checkGLcall ( " glActiveTextureARB " ) ;
LEAVE_GL ( ) ;
2007-02-20 22:44:45 +01:00
2005-11-23 20:14:43 +01:00
/* Make sure the surface is loaded and up to date */
2010-04-26 11:02:34 +02:00
surface_internal_preload ( dst_impl , SRGB_RGB ) ;
2010-03-31 11:28:56 +02:00
IWineD3DSurface_BindTexture ( dst_surface , FALSE ) ;
2005-07-12 19:02:47 +02:00
2010-03-31 11:28:57 +02:00
src_w = src_impl - > currentDesc . Width ;
src_h = src_impl - > currentDesc . Height ;
2010-03-31 11:28:56 +02:00
update_w = src_rect ? src_rect - > right - src_rect - > left : src_w ;
update_h = src_rect ? src_rect - > bottom - src_rect - > top : src_h ;
2005-07-12 19:02:47 +02:00
2010-03-31 11:28:56 +02:00
data = IWineD3DSurface_GetData ( src_surface ) ;
2010-03-30 11:24:47 +02:00
if ( ! data ) ERR ( " Source surface has no allocated memory, but should be a sysmem surface. \n " ) ;
2005-11-04 12:13:45 +01:00
2008-10-19 02:05:10 +02:00
ENTER_GL ( ) ;
2010-03-30 11:24:48 +02:00
if ( dst_format - > Flags & WINED3DFMT_FLAG_COMPRESSED )
2010-03-25 22:51:26 +01:00
{
2010-03-31 11:28:56 +02:00
UINT row_length = ( update_w / src_format - > block_width ) * src_format - > block_byte_count ;
UINT row_count = update_h / src_format - > block_height ;
UINT src_pitch = IWineD3DSurface_GetPitch ( src_surface ) ;
2010-03-30 11:24:44 +02:00
2010-03-31 11:28:56 +02:00
if ( src_rect )
2010-03-25 22:51:26 +01:00
{
2010-03-31 11:28:56 +02:00
data + = ( src_rect - > top / src_format - > block_height ) * src_pitch ;
data + = ( src_rect - > left / src_format - > block_width ) * src_format - > block_byte_count ;
2010-03-30 11:24:46 +02:00
}
2010-03-30 11:24:47 +02:00
TRACE ( " glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, "
" format %#x, image_size %#x, data %p. \n " , dst_impl - > texture_target , dst_impl - > texture_level ,
2010-03-31 11:28:56 +02:00
dst_x , dst_y , update_w , update_h , dst_format - > glFormat , row_count * row_length , data ) ;
2010-03-30 11:24:47 +02:00
2010-03-30 11:24:46 +02:00
if ( row_length = = src_pitch )
{
GL_EXTCALL ( glCompressedTexSubImage2DARB ( dst_impl - > texture_target , dst_impl - > texture_level ,
2010-03-31 11:28:56 +02:00
dst_x , dst_y , update_w , update_h , dst_format - > glInternal , row_count * row_length , data ) ) ;
2010-03-30 11:24:46 +02:00
}
else
{
UINT row , y ;
2005-07-12 19:02:47 +02:00
2010-03-30 11:24:46 +02:00
/* glCompressedTexSubImage2DARB() ignores pixel store state, so we
* can ' t use the unpack row length like below . */
2010-03-31 11:28:56 +02:00
for ( row = 0 , y = dst_y ; row < row_count ; + + row )
2010-03-25 22:51:26 +01:00
{
GL_EXTCALL ( glCompressedTexSubImage2DARB ( dst_impl - > texture_target , dst_impl - > texture_level ,
2010-03-31 11:28:56 +02:00
dst_x , y , update_w , src_format - > block_height , dst_format - > glInternal , row_length , data ) ) ;
2010-03-30 11:24:48 +02:00
y + = src_format - > block_height ;
2010-03-25 22:51:26 +01:00
data + = src_pitch ;
}
2005-07-12 19:02:47 +02:00
}
2010-03-30 11:24:44 +02:00
checkGLcall ( " glCompressedTexSubImage2DARB " ) ;
}
else
{
2010-03-31 11:28:56 +02:00
if ( src_rect )
2010-03-30 11:24:47 +02:00
{
2010-03-31 11:28:56 +02:00
data + = src_rect - > top * src_w * src_format - > byte_count ;
data + = src_rect - > left * src_format - > byte_count ;
2010-03-30 11:24:47 +02:00
}
TRACE ( " glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, data %p. \n " ,
2010-03-31 11:28:56 +02:00
dst_impl - > texture_target , dst_impl - > texture_level , dst_x , dst_y ,
update_w , update_h , dst_format - > glFormat , dst_format - > glType , data ) ;
2010-03-30 11:24:44 +02:00
2010-03-31 11:28:56 +02:00
glPixelStorei ( GL_UNPACK_ROW_LENGTH , src_w ) ;
glTexSubImage2D ( dst_impl - > texture_target , dst_impl - > texture_level , dst_x , dst_y ,
update_w , update_h , dst_format - > glFormat , dst_format - > glType , data ) ;
2010-03-30 11:24:44 +02:00
glPixelStorei ( GL_UNPACK_ROW_LENGTH , 0 ) ;
checkGLcall ( " glTexSubImage2D " ) ;
}
2005-07-12 19:02:47 +02:00
LEAVE_GL ( ) ;
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2005-07-12 19:02:47 +02:00
2010-03-31 11:28:56 +02:00
IWineD3DSurface_ModifyLocation ( dst_surface , SFLAG_INTEXTURE , TRUE ) ;
2008-07-15 23:54:44 +02:00
sampler = This - > rev_tex_unit_map [ 0 ] ;
2009-08-17 09:39:07 +02:00
if ( sampler ! = WINED3D_UNMAPPED_STAGE )
{
2008-07-15 23:54:44 +02:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( sampler ) ) ;
}
2007-02-20 22:44:45 +01:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-01-26 21:54:00 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_DrawRectPatch ( IWineD3DDevice * iface , UINT Handle , CONST float * pNumSegs , CONST WINED3DRECTPATCH_INFO * pRectPatchInfo ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-07-04 17:57:45 +02:00
struct WineD3DRectPatch * patch ;
2009-03-05 12:30:43 +01:00
GLenum old_primitive_type ;
2007-07-04 17:57:45 +02:00
unsigned int i ;
struct list * e ;
BOOL found ;
2005-11-10 13:14:56 +01:00
TRACE ( " (%p) Handle(%d) noSegs(%p) rectpatch(%p) \n " , This , Handle , pNumSegs , pRectPatchInfo ) ;
2004-10-07 06:22:21 +02:00
2007-07-04 17:57:45 +02:00
if ( ! ( Handle | | pRectPatchInfo ) ) {
/* TODO: Write a test for the return value, thus the FIXME */
FIXME ( " Both Handle and pRectPatchInfo are NULL \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
if ( Handle ) {
i = PATCHMAP_HASHFUNC ( Handle ) ;
found = FALSE ;
LIST_FOR_EACH ( e , & This - > patches [ i ] ) {
patch = LIST_ENTRY ( e , struct WineD3DRectPatch , entry ) ;
if ( patch - > Handle = = Handle ) {
found = TRUE ;
break ;
}
}
if ( ! found ) {
TRACE ( " Patch does not exist. Creating a new one \n " ) ;
patch = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * patch ) ) ;
patch - > Handle = Handle ;
list_add_head ( & This - > patches [ i ] , & patch - > entry ) ;
} else {
TRACE ( " Found existing patch %p \n " , patch ) ;
}
} else {
/* Since opengl does not load tesselated vertex attributes into numbered vertex
* attributes we have to tesselate , read back , and draw . This needs a patch
* management structure instance . Create one .
*
* A possible improvement is to check if a vertex shader is used , and if not directly
* draw the patch .
*/
FIXME ( " Drawing an uncached patch. This is slow \n " ) ;
patch = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * patch ) ) ;
}
if ( pNumSegs [ 0 ] ! = patch - > numSegs [ 0 ] | | pNumSegs [ 1 ] ! = patch - > numSegs [ 1 ] | |
pNumSegs [ 2 ] ! = patch - > numSegs [ 2 ] | | pNumSegs [ 3 ] ! = patch - > numSegs [ 3 ] | |
( pRectPatchInfo & & memcmp ( pRectPatchInfo , & patch - > RectPatchInfo , sizeof ( * pRectPatchInfo ) ) ! = 0 ) ) {
HRESULT hr ;
TRACE ( " Tesselation density or patch info changed, retesselating \n " ) ;
if ( pRectPatchInfo ) {
2008-03-20 23:25:13 +01:00
patch - > RectPatchInfo = * pRectPatchInfo ;
2007-07-04 17:57:45 +02:00
}
patch - > numSegs [ 0 ] = pNumSegs [ 0 ] ;
patch - > numSegs [ 1 ] = pNumSegs [ 1 ] ;
patch - > numSegs [ 2 ] = pNumSegs [ 2 ] ;
patch - > numSegs [ 3 ] = pNumSegs [ 3 ] ;
hr = tesselate_rectpatch ( This , patch ) ;
if ( FAILED ( hr ) ) {
WARN ( " Patch tesselation failed \n " ) ;
/* Do not release the handle to store the params of the patch */
if ( ! Handle ) {
HeapFree ( GetProcessHeap ( ) , 0 , patch ) ;
}
return hr ;
}
}
This - > currentPatch = patch ;
2009-03-05 12:30:43 +01:00
old_primitive_type = This - > stateBlock - > gl_primitive_type ;
This - > stateBlock - > gl_primitive_type = GL_TRIANGLES ;
2009-03-20 19:16:52 +01:00
IWineD3DDevice_DrawPrimitiveStrided ( iface , patch - > numSegs [ 0 ] * patch - > numSegs [ 1 ] * 2 * 3 , & patch - > strided ) ;
2009-03-05 12:30:43 +01:00
This - > stateBlock - > gl_primitive_type = old_primitive_type ;
2007-07-04 17:57:45 +02:00
This - > currentPatch = NULL ;
/* Destroy uncached patches */
if ( ! Handle ) {
HeapFree ( GetProcessHeap ( ) , 0 , patch - > mem ) ;
HeapFree ( GetProcessHeap ( ) , 0 , patch ) ;
}
return WINED3D_OK ;
2004-10-07 06:22:21 +02:00
}
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_DrawTriPatch ( IWineD3DDevice * iface ,
UINT handle , const float * segment_count , const WINED3DTRIPATCH_INFO * patch_info )
{
FIXME ( " iface %p, handle %#x, segment_count %p, patch_info %p stub! \n " ,
iface , handle , segment_count , patch_info ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-12 20:50:22 +01:00
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_DeletePatch ( IWineD3DDevice * iface , UINT Handle ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2007-07-04 17:57:45 +02:00
int i ;
struct WineD3DRectPatch * patch ;
struct list * e ;
2005-03-02 13:16:10 +01:00
TRACE ( " (%p) Handle(%d) \n " , This , Handle ) ;
2007-07-04 17:57:45 +02:00
i = PATCHMAP_HASHFUNC ( Handle ) ;
LIST_FOR_EACH ( e , & This - > patches [ i ] ) {
patch = LIST_ENTRY ( e , struct WineD3DRectPatch , entry ) ;
if ( patch - > Handle = = Handle ) {
TRACE ( " Deleting patch %p \n " , patch ) ;
list_remove ( & patch - > entry ) ;
HeapFree ( GetProcessHeap ( ) , 0 , patch - > mem ) ;
HeapFree ( GetProcessHeap ( ) , 0 , patch ) ;
return WINED3D_OK ;
}
}
/* TODO: Write a test for the return value */
2007-12-07 21:01:34 +01:00
FIXME ( " Attempt to destroy nonexistent patch \n " ) ;
2007-07-04 17:57:45 +02:00
return WINED3DERR_INVALIDCALL ;
2005-07-13 16:15:54 +02:00
}
2005-03-02 13:16:10 +01:00
2010-04-21 22:02:33 +02:00
static void color_fill_fbo ( IWineD3DDevice * iface , IWineD3DSurfaceImpl * surface ,
2009-02-25 08:39:01 +01:00
const WINED3DRECT * rect , const float color [ 4 ] )
{
2007-04-16 21:21:13 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-08-03 08:06:51 +02:00
struct wined3d_context * context ;
2007-04-16 21:21:13 +02:00
2010-04-21 22:02:33 +02:00
if ( rect ) IWineD3DSurface_LoadLocation ( ( IWineD3DSurface * ) surface , SFLAG_INDRAWABLE , NULL ) ;
IWineD3DSurface_ModifyLocation ( ( IWineD3DSurface * ) surface , SFLAG_INDRAWABLE , TRUE ) ;
2010-02-03 11:02:24 +01:00
2010-04-21 22:02:33 +02:00
if ( ! surface_is_offscreen ( surface ) )
2009-12-10 21:41:52 +01:00
{
2007-04-16 21:21:13 +02:00
TRACE ( " Surface %p is onscreen \n " , surface ) ;
2010-04-21 22:02:33 +02:00
context = context_acquire ( This , surface , CTXUSAGE_RESOURCELOAD ) ;
2008-07-30 00:24:43 +02:00
ENTER_GL ( ) ;
2009-09-23 10:05:55 +02:00
context_bind_fbo ( context , GL_FRAMEBUFFER , NULL ) ;
2010-04-21 22:02:33 +02:00
context_set_draw_buffer ( context , surface_get_gl_buffer ( surface ) ) ;
2009-12-10 21:41:52 +01:00
}
else
{
2007-04-16 21:21:13 +02:00
TRACE ( " Surface %p is offscreen \n " , surface ) ;
2008-07-30 00:24:43 +02:00
2009-10-28 11:00:11 +01:00
context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2008-07-30 00:24:43 +02:00
ENTER_GL ( ) ;
2009-09-23 10:05:55 +02:00
context_bind_fbo ( context , GL_FRAMEBUFFER , & context - > dst_fbo ) ;
2010-04-21 22:02:33 +02:00
context_attach_surface_fbo ( context , GL_FRAMEBUFFER , 0 , surface ) ;
2009-09-23 10:05:55 +02:00
context_attach_depth_stencil_fbo ( context , GL_FRAMEBUFFER , NULL , FALSE ) ;
2007-04-16 21:21:13 +02:00
}
if ( rect ) {
glEnable ( GL_SCISSOR_TEST ) ;
2010-04-21 22:02:33 +02:00
if ( surface_is_offscreen ( surface ) )
2007-04-16 21:21:13 +02:00
glScissor ( rect - > x1 , rect - > y1 , rect - > x2 - rect - > x1 , rect - > y2 - rect - > y1 ) ;
2010-04-18 22:50:45 +02:00
else
2010-04-21 22:02:33 +02:00
glScissor ( rect - > x1 , surface - > currentDesc . Height - rect - > y2 ,
2007-04-16 21:21:13 +02:00
rect - > x2 - rect - > x1 , rect - > y2 - rect - > y1 ) ;
checkGLcall ( " glScissor " ) ;
2008-08-04 19:28:32 +02:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SCISSORRECT ) ;
2007-04-16 21:21:13 +02:00
} else {
glDisable ( GL_SCISSOR_TEST ) ;
}
2008-08-03 21:17:57 +02:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_SCISSORTESTENABLE ) ) ;
glDisable ( GL_BLEND ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_ALPHABLENDENABLE ) ) ;
2007-04-16 21:21:13 +02:00
glColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE ) ) ;
2010-03-25 22:51:22 +01:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE1 ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE2 ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_COLORWRITEENABLE3 ) ) ;
2007-04-16 21:21:13 +02:00
2009-02-25 08:39:01 +01:00
glClearColor ( color [ 0 ] , color [ 1 ] , color [ 2 ] , color [ 3 ] ) ;
2007-04-16 21:21:13 +02:00
glClear ( GL_COLOR_BUFFER_BIT ) ;
checkGLcall ( " glClear " ) ;
2008-07-30 00:24:43 +02:00
LEAVE_GL ( ) ;
2010-01-27 20:19:40 +01:00
2010-04-13 20:46:26 +02:00
if ( wined3d_settings . strict_draw_ordering ) wglFlush ( ) ; /* Flush to ensure ordering across contexts. */
2010-01-27 20:19:40 +01:00
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2007-04-16 21:21:13 +02:00
}
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill ( IWineD3DDevice * iface ,
IWineD3DSurface * pSurface , const WINED3DRECT * pRect , WINED3DCOLOR color )
{
2006-07-22 17:37:51 +02:00
IWineD3DSurfaceImpl * surface = ( IWineD3DSurfaceImpl * ) pSurface ;
2007-04-14 22:44:55 +02:00
WINEDDBLTFX BltFx ;
2009-12-21 23:17:26 +01:00
TRACE ( " iface %p, surface %p, rect %p, color 0x%08x. \n " , iface , pSurface , pRect , color ) ;
2005-08-22 11:13:49 +02:00
2006-05-18 22:59:33 +02:00
if ( surface - > resource . pool ! = WINED3DPOOL_DEFAULT & & surface - > resource . pool ! = WINED3DPOOL_SYSTEMMEM ) {
FIXME ( " call to colorfill with non WINED3DPOOL_DEFAULT or WINED3DPOOL_SYSTEMMEM surface \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-07-18 12:32:00 +02:00
}
2005-03-02 13:16:10 +01:00
2007-04-16 21:21:13 +02:00
if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO ) {
2009-02-25 08:39:01 +01:00
const float c [ 4 ] = { D3DCOLOR_R ( color ) , D3DCOLOR_G ( color ) , D3DCOLOR_B ( color ) , D3DCOLOR_A ( color ) } ;
2010-04-21 22:02:33 +02:00
color_fill_fbo ( iface , surface , pRect , c ) ;
2007-04-27 00:17:54 +02:00
return WINED3D_OK ;
2007-04-16 21:21:13 +02:00
} else {
/* Just forward this to the DirectDraw blitting engine */
memset ( & BltFx , 0 , sizeof ( BltFx ) ) ;
BltFx . dwSize = sizeof ( BltFx ) ;
2010-03-25 16:30:13 +01:00
BltFx . u5 . dwFillColor = color_convert_argb_to_fmt ( color , surface - > resource . format_desc - > format ) ;
2008-11-25 11:57:39 +01:00
return IWineD3DSurface_Blt ( pSurface , ( const RECT * ) pRect , NULL , NULL ,
2009-08-05 09:01:03 +02:00
WINEDDBLT_COLORFILL , & BltFx , WINED3DTEXF_POINT ) ;
2007-04-16 21:21:13 +02:00
}
2004-10-07 06:22:21 +02:00
}
2009-02-25 08:39:01 +01:00
static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView ( IWineD3DDevice * iface ,
IWineD3DRendertargetView * rendertarget_view , const float color [ 4 ] )
{
IWineD3DResource * resource ;
2010-04-21 22:02:33 +02:00
IWineD3DSurfaceImpl * surface ;
2009-02-25 08:39:01 +01:00
HRESULT hr ;
hr = IWineD3DRendertargetView_GetResource ( rendertarget_view , & resource ) ;
if ( FAILED ( hr ) )
{
ERR ( " Failed to get resource, hr %#x \n " , hr ) ;
return ;
}
if ( IWineD3DResource_GetType ( resource ) ! = WINED3DRTYPE_SURFACE )
{
FIXME ( " Only supported on surface resources \n " ) ;
IWineD3DResource_Release ( resource ) ;
return ;
}
2010-04-21 22:02:33 +02:00
surface = ( IWineD3DSurfaceImpl * ) resource ;
2009-02-25 08:39:01 +01:00
if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO )
{
color_fill_fbo ( iface , surface , NULL , color ) ;
}
else
{
WINEDDBLTFX BltFx ;
WINED3DCOLOR c ;
WARN ( " Converting to WINED3DCOLOR, this might give incorrect results \n " ) ;
2009-07-07 11:08:01 +02:00
c = ( ( DWORD ) ( color [ 2 ] * 255.0f ) ) ;
c | = ( ( DWORD ) ( color [ 1 ] * 255.0f ) ) < < 8 ;
c | = ( ( DWORD ) ( color [ 0 ] * 255.0f ) ) < < 16 ;
c | = ( ( DWORD ) ( color [ 3 ] * 255.0f ) ) < < 24 ;
2009-02-25 08:39:01 +01:00
/* Just forward this to the DirectDraw blitting engine */
memset ( & BltFx , 0 , sizeof ( BltFx ) ) ;
BltFx . dwSize = sizeof ( BltFx ) ;
2010-04-21 22:02:33 +02:00
BltFx . u5 . dwFillColor = color_convert_argb_to_fmt ( c , surface - > resource . format_desc - > format ) ;
hr = IWineD3DSurface_Blt ( ( IWineD3DSurface * ) surface , NULL , NULL , NULL ,
WINEDDBLT_COLORFILL , & BltFx , WINED3DTEXF_POINT ) ;
2009-02-25 08:39:01 +01:00
if ( FAILED ( hr ) )
{
ERR ( " Blt failed, hr %#x \n " , hr ) ;
}
}
IWineD3DResource_Release ( resource ) ;
}
2008-01-09 20:37:05 +01:00
/* rendertarget and depth stencil functions */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTarget ( IWineD3DDevice * iface , DWORD RenderTargetIndex , IWineD3DSurface * * ppRenderTarget ) {
2004-10-07 06:22:21 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
2009-10-29 10:37:10 +01:00
if ( RenderTargetIndex > = This - > adapter - > gl_info . limits . buffers )
2009-10-22 10:09:54 +02:00
{
ERR ( " (%p) : Only %d render targets are supported. \n " ,
2009-10-29 10:37:10 +01:00
This , This - > adapter - > gl_info . limits . buffers ) ;
2006-12-19 19:25:42 +01:00
return WINED3DERR_INVALIDCALL ;
}
2005-07-13 16:15:54 +02:00
2010-04-19 20:46:59 +02:00
* ppRenderTarget = ( IWineD3DSurface * ) This - > render_targets [ RenderTargetIndex ] ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : RenderTarget %d Index returning %p \n " , This , RenderTargetIndex , * ppRenderTarget ) ;
2006-11-30 13:33:46 +01:00
/* Note inc ref on returned surface */
if ( * ppRenderTarget ! = NULL )
IWineD3DSurface_AddRef ( * ppRenderTarget ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2005-01-12 20:50:22 +01:00
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers ( IWineD3DDevice * iface ,
2010-03-16 19:02:20 +01:00
IWineD3DSurface * front , IWineD3DSurface * back )
2009-12-21 23:17:26 +01:00
{
2010-03-16 19:02:20 +01:00
IWineD3DSurfaceImpl * front_impl = ( IWineD3DSurfaceImpl * ) front ;
IWineD3DSurfaceImpl * back_impl = ( IWineD3DSurfaceImpl * ) back ;
IWineD3DSwapChainImpl * swapchain ;
2006-05-15 20:09:07 +02:00
HRESULT hr ;
2010-03-16 19:02:20 +01:00
TRACE ( " iface %p, front %p, back %p. \n " , iface , front , back ) ;
2006-05-15 20:09:07 +02:00
2010-03-16 19:02:20 +01:00
if ( FAILED ( hr = IWineD3DDevice_GetSwapChain ( iface , 0 , ( IWineD3DSwapChain * * ) & swapchain ) ) )
{
ERR ( " Failed to get the swapchain, hr %#x. \n " , hr ) ;
2006-05-15 20:09:07 +02:00
return hr ;
}
2010-03-16 19:02:20 +01:00
if ( front_impl & & ! ( front_impl - > resource . usage & WINED3DUSAGE_RENDERTARGET ) )
{
ERR ( " Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage. \n " ) ;
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
2006-05-15 20:09:07 +02:00
return WINED3DERR_INVALIDCALL ;
}
2010-03-16 19:02:20 +01:00
if ( back_impl )
{
if ( ! ( back_impl - > resource . usage & WINED3DUSAGE_RENDERTARGET ) )
2009-03-25 10:12:27 +01:00
{
2010-03-16 19:02:20 +01:00
ERR ( " Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage. \n " ) ;
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
return WINED3DERR_INVALIDCALL ;
2009-03-25 10:12:27 +01:00
}
2006-05-15 20:09:07 +02:00
2010-04-26 21:33:01 +02:00
if ( ! swapchain - > back_buffers )
2010-03-16 19:02:20 +01:00
{
2010-04-26 21:33:01 +02:00
swapchain - > back_buffers = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * swapchain - > back_buffers ) ) ;
if ( ! swapchain - > back_buffers )
2010-03-16 19:02:20 +01:00
{
ERR ( " Failed to allocate back buffer array memory. \n " ) ;
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
return E_OUTOFMEMORY ;
}
2006-05-15 20:09:07 +02:00
}
}
2006-06-15 12:54:19 +02:00
2010-04-26 21:33:00 +02:00
if ( swapchain - > front_buffer ! = front_impl )
2010-03-16 19:02:20 +01:00
{
2010-04-26 21:33:00 +02:00
TRACE ( " Changing the front buffer from %p to %p. \n " , swapchain - > front_buffer , front_impl ) ;
2010-03-16 19:02:20 +01:00
2010-04-26 21:33:00 +02:00
if ( swapchain - > front_buffer )
2010-03-16 19:02:20 +01:00
{
2010-04-26 21:33:00 +02:00
IWineD3DSurface_SetContainer ( ( IWineD3DSurface * ) swapchain - > front_buffer , NULL ) ;
swapchain - > front_buffer - > Flags & = ~ SFLAG_SWAPCHAIN ;
2010-03-16 19:02:20 +01:00
}
2010-04-26 21:33:00 +02:00
swapchain - > front_buffer = front_impl ;
2010-03-16 19:02:20 +01:00
if ( front )
{
IWineD3DSurface_SetContainer ( front , ( IWineD3DBase * ) swapchain ) ;
front_impl - > Flags | = SFLAG_SWAPCHAIN ;
2006-06-15 12:54:19 +02:00
}
}
2010-04-26 21:33:01 +02:00
if ( swapchain - > back_buffers [ 0 ] ! = back_impl )
2010-03-16 19:02:20 +01:00
{
2010-04-26 21:33:01 +02:00
TRACE ( " Changing the back buffer from %p to %p. \n " , swapchain - > back_buffers [ 0 ] , back_impl ) ;
2007-03-17 23:00:39 +01:00
2010-04-26 21:33:01 +02:00
if ( swapchain - > back_buffers [ 0 ] )
2010-03-16 19:02:20 +01:00
{
2010-04-26 21:33:01 +02:00
IWineD3DSurface_SetContainer ( ( IWineD3DSurface * ) swapchain - > back_buffers [ 0 ] , NULL ) ;
swapchain - > back_buffers [ 0 ] - > Flags & = ~ SFLAG_SWAPCHAIN ;
2010-03-16 19:02:20 +01:00
}
2010-04-26 21:33:01 +02:00
swapchain - > back_buffers [ 0 ] = back_impl ;
2006-05-15 20:09:07 +02:00
2010-03-16 19:02:20 +01:00
if ( back )
2009-03-25 10:12:27 +01:00
{
2010-03-16 19:02:20 +01:00
swapchain - > presentParms . BackBufferWidth = back_impl - > currentDesc . Width ;
swapchain - > presentParms . BackBufferHeight = back_impl - > currentDesc . Height ;
swapchain - > presentParms . BackBufferFormat = back_impl - > resource . format_desc - > format ;
swapchain - > presentParms . BackBufferCount = 1 ;
IWineD3DSurface_SetContainer ( back , ( IWineD3DBase * ) swapchain ) ;
back_impl - > Flags | = SFLAG_SWAPCHAIN ;
2009-03-25 10:12:27 +01:00
}
2010-03-16 19:02:20 +01:00
else
{
swapchain - > presentParms . BackBufferCount = 0 ;
2010-04-26 21:33:01 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , swapchain - > back_buffers ) ;
swapchain - > back_buffers = NULL ;
2006-05-15 20:09:07 +02:00
}
}
2010-03-16 19:02:20 +01:00
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
2006-05-15 20:09:07 +02:00
return WINED3D_OK ;
2006-04-15 22:40:14 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface ( IWineD3DDevice * iface , IWineD3DSurface * * ppZStencilSurface ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2010-04-19 20:47:01 +02:00
* ppZStencilSurface = ( IWineD3DSurface * ) This - > depth_stencil ;
2005-03-02 13:16:10 +01:00
TRACE ( " (%p) : zStencilSurface returning %p \n " , This , * ppZStencilSurface ) ;
2005-01-12 20:50:22 +01:00
2006-11-30 13:33:40 +01:00
if ( * ppZStencilSurface ! = NULL ) {
/* Note inc ref on returned surface */
IWineD3DSurface_AddRef ( * ppZStencilSurface ) ;
2007-08-31 20:58:35 +02:00
return WINED3D_OK ;
} else {
return WINED3DERR_NOTFOUND ;
2006-11-30 13:33:40 +01:00
}
2005-03-02 13:16:10 +01:00
}
2010-04-20 22:38:43 +02:00
void stretch_rect_fbo ( IWineD3DDeviceImpl * device , IWineD3DSurfaceImpl * src_surface , const RECT * src_rect_in ,
IWineD3DSurfaceImpl * dst_surface , const RECT * dst_rect_in , const WINED3DTEXTUREFILTERTYPE filter )
2008-11-26 16:14:39 +01:00
{
2007-04-09 01:54:07 +02:00
GLbitfield mask = GL_COLOR_BUFFER_BIT ; /* TODO: Support blitting depth/stencil surfaces */
2009-09-23 10:05:55 +02:00
const struct wined3d_gl_info * gl_info ;
2009-08-03 08:06:51 +02:00
struct wined3d_context * context ;
2007-04-09 01:54:07 +02:00
GLenum gl_filter ;
2008-08-03 18:33:07 +02:00
POINT offset = { 0 , 0 } ;
2010-03-30 22:18:58 +02:00
RECT src_rect , dst_rect ;
2007-04-09 01:54:07 +02:00
2010-04-20 22:38:43 +02:00
TRACE ( " device %p, src_surface %p, src_rect_in %s, dst_surface %p, dst_rect_in %s, filter %s (0x%08x). \n " ,
device , src_surface , wine_dbgstr_rect ( src_rect_in ) , dst_surface ,
wine_dbgstr_rect ( dst_rect_in ) , debug_d3dtexturefiltertype ( filter ) , filter ) ;
2010-03-30 22:18:58 +02:00
src_rect = * src_rect_in ;
dst_rect = * dst_rect_in ;
2007-04-09 01:54:07 +02:00
switch ( filter ) {
case WINED3DTEXF_LINEAR :
gl_filter = GL_LINEAR ;
break ;
default :
FIXME ( " Unsupported filter mode %s (0x%08x) \n " , debug_d3dtexturefiltertype ( filter ) , filter ) ;
case WINED3DTEXF_NONE :
case WINED3DTEXF_POINT :
gl_filter = GL_NEAREST ;
break ;
}
2010-02-03 11:02:23 +01:00
/* Make sure the drawables are up-to-date. Note that loading the
* destination surface isn ' t strictly required if we overwrite the
* entire surface . */
2010-04-20 22:38:43 +02:00
IWineD3DSurface_LoadLocation ( ( IWineD3DSurface * ) src_surface , SFLAG_INDRAWABLE , NULL ) ;
IWineD3DSurface_LoadLocation ( ( IWineD3DSurface * ) dst_surface , SFLAG_INDRAWABLE , NULL ) ;
2010-02-03 11:02:23 +01:00
2010-04-21 22:02:32 +02:00
if ( ! surface_is_offscreen ( src_surface ) ) context = context_acquire ( device , src_surface , CTXUSAGE_RESOURCELOAD ) ;
else if ( ! surface_is_offscreen ( dst_surface ) ) context = context_acquire ( device , dst_surface , CTXUSAGE_RESOURCELOAD ) ;
2010-04-20 22:38:43 +02:00
else context = context_acquire ( device , NULL , CTXUSAGE_RESOURCELOAD ) ;
2009-06-18 09:04:02 +02:00
2010-03-17 21:59:54 +01:00
if ( ! context - > valid )
{
context_release ( context ) ;
WARN ( " Invalid context, skipping blit. \n " ) ;
return ;
}
2009-09-23 10:05:55 +02:00
gl_info = context - > gl_info ;
2010-04-20 22:38:43 +02:00
if ( ! surface_is_offscreen ( src_surface ) )
2009-12-15 17:51:36 +01:00
{
2010-04-20 22:38:43 +02:00
GLenum buffer = surface_get_gl_buffer ( src_surface ) ;
2007-04-16 21:20:56 +02:00
2007-04-10 19:13:44 +02:00
TRACE ( " Source surface %p is onscreen \n " , src_surface ) ;
2007-04-16 21:20:56 +02:00
2008-08-03 18:33:07 +02:00
if ( buffer = = GL_FRONT ) {
RECT windowsize ;
UINT h ;
2010-03-15 21:07:26 +01:00
ClientToScreen ( context - > win_handle , & offset ) ;
GetClientRect ( context - > win_handle , & windowsize ) ;
2008-08-03 18:33:07 +02:00
h = windowsize . bottom - windowsize . top ;
2010-03-30 22:18:58 +02:00
src_rect . left - = offset . x ; src_rect . right - = offset . x ;
src_rect . top = offset . y + h - src_rect . top ;
src_rect . bottom = offset . y + h - src_rect . bottom ;
2008-08-03 18:33:07 +02:00
} else {
2010-04-20 22:38:43 +02:00
src_rect . top = src_surface - > currentDesc . Height - src_rect . top ;
src_rect . bottom = src_surface - > currentDesc . Height - src_rect . bottom ;
2008-08-03 18:33:07 +02:00
}
2007-08-06 16:27:08 +02:00
ENTER_GL ( ) ;
2009-09-23 10:05:55 +02:00
context_bind_fbo ( context , GL_READ_FRAMEBUFFER , NULL ) ;
2007-04-16 21:20:56 +02:00
glReadBuffer ( buffer ) ;
checkGLcall ( " glReadBuffer() " ) ;
2007-04-09 01:54:07 +02:00
} else {
2007-04-10 19:13:44 +02:00
TRACE ( " Source surface %p is offscreen \n " , src_surface ) ;
2007-08-06 16:27:08 +02:00
ENTER_GL ( ) ;
2009-09-23 10:05:55 +02:00
context_bind_fbo ( context , GL_READ_FRAMEBUFFER , & context - > src_fbo ) ;
2010-04-20 22:38:43 +02:00
context_attach_surface_fbo ( context , GL_READ_FRAMEBUFFER , 0 , src_surface ) ;
2009-09-23 10:05:55 +02:00
glReadBuffer ( GL_COLOR_ATTACHMENT0 ) ;
2007-04-16 21:20:56 +02:00
checkGLcall ( " glReadBuffer() " ) ;
2009-09-23 10:05:55 +02:00
context_attach_depth_stencil_fbo ( context , GL_READ_FRAMEBUFFER , NULL , FALSE ) ;
2007-04-09 01:54:07 +02:00
}
2007-08-06 16:27:08 +02:00
LEAVE_GL ( ) ;
2007-04-09 01:54:07 +02:00
/* Attach dst surface to dst fbo */
2010-04-20 22:38:43 +02:00
if ( ! surface_is_offscreen ( dst_surface ) )
2009-12-15 17:51:36 +01:00
{
2010-04-20 22:38:43 +02:00
GLenum buffer = surface_get_gl_buffer ( dst_surface ) ;
2007-04-16 21:20:56 +02:00
2007-04-10 19:13:44 +02:00
TRACE ( " Destination surface %p is onscreen \n " , dst_surface ) ;
2007-04-16 21:20:56 +02:00
2008-08-03 18:33:07 +02:00
if ( buffer = = GL_FRONT ) {
RECT windowsize ;
UINT h ;
2010-03-15 21:07:26 +01:00
ClientToScreen ( context - > win_handle , & offset ) ;
GetClientRect ( context - > win_handle , & windowsize ) ;
2008-08-03 18:33:07 +02:00
h = windowsize . bottom - windowsize . top ;
2010-03-30 22:18:58 +02:00
dst_rect . left - = offset . x ; dst_rect . right - = offset . x ;
dst_rect . top = offset . y + h - dst_rect . top ;
dst_rect . bottom = offset . y + h - dst_rect . bottom ;
2008-08-03 18:33:07 +02:00
} else {
/* Screen coords = window coords, surface height = window height */
2010-04-20 22:38:43 +02:00
dst_rect . top = dst_surface - > currentDesc . Height - dst_rect . top ;
dst_rect . bottom = dst_surface - > currentDesc . Height - dst_rect . bottom ;
2008-08-03 18:33:07 +02:00
}
2007-08-06 16:27:08 +02:00
ENTER_GL ( ) ;
2009-09-23 10:05:55 +02:00
context_bind_fbo ( context , GL_DRAW_FRAMEBUFFER , NULL ) ;
2009-12-13 22:03:58 +01:00
context_set_draw_buffer ( context , buffer ) ;
}
else
{
2007-04-10 19:13:44 +02:00
TRACE ( " Destination surface %p is offscreen \n " , dst_surface ) ;
2007-06-09 14:59:15 +02:00
2007-08-06 16:27:08 +02:00
ENTER_GL ( ) ;
2009-09-23 10:05:55 +02:00
context_bind_fbo ( context , GL_DRAW_FRAMEBUFFER , & context - > dst_fbo ) ;
2010-04-20 22:38:43 +02:00
context_attach_surface_fbo ( context , GL_DRAW_FRAMEBUFFER , 0 , dst_surface ) ;
2009-12-13 22:03:58 +01:00
context_set_draw_buffer ( context , GL_COLOR_ATTACHMENT0 ) ;
2009-09-23 10:05:55 +02:00
context_attach_depth_stencil_fbo ( context , GL_DRAW_FRAMEBUFFER , NULL , FALSE ) ;
2007-04-09 01:54:07 +02:00
}
2007-06-09 14:59:15 +02:00
glDisable ( GL_SCISSOR_TEST ) ;
2010-04-20 22:38:43 +02:00
IWineD3DDeviceImpl_MarkStateDirty ( device , STATE_RENDER ( WINED3DRS_SCISSORTESTENABLE ) ) ;
2007-04-09 01:54:07 +02:00
2010-04-01 23:58:49 +02:00
gl_info - > fbo_ops . glBlitFramebuffer ( src_rect . left , src_rect . top , src_rect . right , src_rect . bottom ,
dst_rect . left , dst_rect . top , dst_rect . right , dst_rect . bottom , mask , gl_filter ) ;
checkGLcall ( " glBlitFramebuffer() " ) ;
2007-04-09 01:54:07 +02:00
2007-06-09 14:59:15 +02:00
LEAVE_GL ( ) ;
2010-01-27 20:19:40 +01:00
2010-04-13 20:46:26 +02:00
if ( wined3d_settings . strict_draw_ordering ) wglFlush ( ) ; /* Flush to ensure ordering across contexts. */
2010-01-27 20:19:40 +01:00
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2009-12-13 22:03:58 +01:00
2010-04-20 22:38:43 +02:00
IWineD3DSurface_ModifyLocation ( ( IWineD3DSurface * ) dst_surface , SFLAG_INDRAWABLE , TRUE ) ;
2007-04-09 01:54:07 +02:00
}
2009-10-20 14:13:26 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget ( IWineD3DDevice * iface , DWORD RenderTargetIndex , IWineD3DSurface * pRenderTarget ,
BOOL set_viewport ) {
2005-07-07 22:35:05 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-03-02 13:16:10 +01:00
2006-12-19 19:25:42 +01:00
TRACE ( " (%p) : Setting rendertarget %d to %p \n " , This , RenderTargetIndex , pRenderTarget ) ;
2009-10-29 10:37:10 +01:00
if ( RenderTargetIndex > = This - > adapter - > gl_info . limits . buffers )
2009-10-22 10:09:54 +02:00
{
2007-11-20 21:16:25 +01:00
WARN ( " (%p) : Unsupported target %u set, returning WINED3DERR_INVALIDCALL(only %u supported) \n " ,
2009-10-29 10:37:10 +01:00
This , RenderTargetIndex , This - > adapter - > gl_info . limits . buffers ) ;
2006-12-19 19:25:42 +01:00
return WINED3DERR_INVALIDCALL ;
2005-07-07 22:35:05 +02:00
}
/* MSDN says that null disables the render target
2005-07-11 12:59:41 +02:00
but a device must always be associated with a render target
2005-07-07 22:35:05 +02:00
nope MSDN says that we return invalid call to a null rendertarget with an index of 0
*/
if ( RenderTargetIndex = = 0 & & pRenderTarget = = NULL ) {
FIXME ( " Trying to set render target 0 to NULL \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-07-07 22:35:05 +02:00
}
2007-12-02 14:14:30 +01:00
if ( pRenderTarget & & ! ( ( ( IWineD3DSurfaceImpl * ) pRenderTarget ) - > resource . usage & WINED3DUSAGE_RENDERTARGET ) ) {
2006-03-06 23:08:42 +01:00
FIXME ( " (%p)Trying to set the render target to a surface(%p) that wasn't created with a usage of WINED3DUSAGE_RENDERTARGET \n " , This , pRenderTarget ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-07-07 22:35:05 +02:00
}
2007-02-12 19:21:10 +01:00
2005-07-07 22:35:05 +02:00
/* If we are trying to set what we already have, don't bother */
2010-04-19 20:46:59 +02:00
if ( pRenderTarget = = ( IWineD3DSurface * ) This - > render_targets [ RenderTargetIndex ] )
{
2005-07-07 22:35:05 +02:00
TRACE ( " Trying to do a NOP SetRenderTarget operation \n " ) ;
2007-02-12 19:21:10 +01:00
return WINED3D_OK ;
2005-07-07 22:35:05 +02:00
}
2010-04-19 20:46:59 +02:00
if ( pRenderTarget )
IWineD3DSurface_AddRef ( pRenderTarget ) ;
if ( This - > render_targets [ RenderTargetIndex ] )
IWineD3DSurface_Release ( ( IWineD3DSurface * ) This - > render_targets [ RenderTargetIndex ] ) ;
This - > render_targets [ RenderTargetIndex ] = ( IWineD3DSurfaceImpl * ) pRenderTarget ;
2005-07-07 22:35:05 +02:00
2007-02-12 19:21:10 +01:00
/* Render target 0 is special */
2009-10-20 14:13:26 +02:00
if ( RenderTargetIndex = = 0 & & set_viewport ) {
2009-09-30 18:59:41 +02:00
/* Finally, reset the viewport and scissor rect as the MSDN states.
* Tests show that stateblock recording is ignored , the change goes
* directly into the primary stateblock .
2009-09-30 18:58:04 +02:00
*/
2010-04-19 20:46:59 +02:00
This - > stateBlock - > viewport . Height = This - > render_targets [ 0 ] - > currentDesc . Height ;
This - > stateBlock - > viewport . Width = This - > render_targets [ 0 ] - > currentDesc . Width ;
2009-09-30 18:58:04 +02:00
This - > stateBlock - > viewport . X = 0 ;
This - > stateBlock - > viewport . Y = 0 ;
This - > stateBlock - > viewport . MaxZ = 1.0f ;
This - > stateBlock - > viewport . MinZ = 0.0f ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_VIEWPORT ) ;
2009-09-30 18:59:41 +02:00
This - > stateBlock - > scissorRect . top = 0 ;
This - > stateBlock - > scissorRect . left = 0 ;
This - > stateBlock - > scissorRect . right = This - > stateBlock - > viewport . Width ;
This - > stateBlock - > scissorRect . bottom = This - > stateBlock - > viewport . Height ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SCISSORRECT ) ;
2005-07-07 22:35:05 +02:00
}
2007-02-12 19:21:10 +01:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface ( IWineD3DDevice * iface , IWineD3DSurface * pNewZStencil ) {
2005-07-07 22:35:05 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2010-04-19 20:47:01 +02:00
IWineD3DSurfaceImpl * tmp ;
2005-07-07 22:35:05 +02:00
2010-04-19 20:47:01 +02:00
TRACE ( " device %p, depth_stencil %p, old depth_stencil %p. \n " , This , pNewZStencil , This - > depth_stencil ) ;
2005-07-07 22:35:05 +02:00
2010-04-19 20:47:01 +02:00
if ( This - > depth_stencil = = ( IWineD3DSurfaceImpl * ) pNewZStencil )
{
TRACE ( " Trying to do a NOP SetRenderTarget operation. \n " ) ;
2010-04-19 20:47:03 +02:00
return WINED3D_OK ;
2010-04-19 20:47:01 +02:00
}
2010-04-19 20:47:03 +02:00
if ( This - > depth_stencil )
2010-04-19 20:47:01 +02:00
{
2010-04-19 20:47:03 +02:00
if ( ( ( IWineD3DSwapChainImpl * ) This - > swapchains [ 0 ] ) - > presentParms . Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
| | This - > depth_stencil - > Flags & SFLAG_DISCARD )
2010-04-19 20:47:01 +02:00
{
2010-04-19 20:47:03 +02:00
surface_modify_ds_location ( This - > depth_stencil , SFLAG_DS_DISCARDED ) ;
2010-04-20 22:38:41 +02:00
if ( This - > depth_stencil = = This - > onscreen_depth_stencil )
{
IWineD3DSurface_Release ( ( IWineD3DSurface * ) This - > onscreen_depth_stencil ) ;
This - > onscreen_depth_stencil = NULL ;
}
2008-07-02 23:00:41 +02:00
}
2010-04-19 20:47:03 +02:00
}
2008-07-02 23:00:41 +02:00
2010-04-19 20:47:03 +02:00
tmp = This - > depth_stencil ;
This - > depth_stencil = ( IWineD3DSurfaceImpl * ) pNewZStencil ;
if ( This - > depth_stencil ) IWineD3DSurface_AddRef ( ( IWineD3DSurface * ) This - > depth_stencil ) ;
if ( tmp ) IWineD3DSurface_Release ( ( IWineD3DSurface * ) tmp ) ;
2007-03-06 13:35:56 +01:00
2010-04-19 20:47:03 +02:00
if ( ( ! tmp & & pNewZStencil ) | | ( ! pNewZStencil & & tmp ) )
{
/* Swapping NULL / non NULL depth stencil affects the depth and tests */
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_ZENABLE ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_STENCILENABLE ) ) ;
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_RENDER ( WINED3DRS_STENCILWRITEMASK ) ) ;
2005-07-07 22:35:05 +02:00
}
2010-04-19 20:47:02 +02:00
return WINED3D_OK ;
2005-07-07 22:35:05 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties ( IWineD3DDevice * iface , UINT XHotSpot ,
2005-03-02 13:16:10 +01:00
UINT YHotSpot , IWineD3DSurface * pCursorBitmap ) {
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-03-23 14:15:18 +01:00
/* TODO: the use of Impl is deprecated. */
2005-03-02 13:16:10 +01:00
IWineD3DSurfaceImpl * pSur = ( IWineD3DSurfaceImpl * ) pCursorBitmap ;
2007-05-15 00:37:53 +02:00
WINED3DLOCKED_RECT lockedRect ;
2005-03-02 13:16:10 +01:00
TRACE ( " (%p) : Spot Pos(%u,%u) \n " , This , XHotSpot , YHotSpot ) ;
2006-07-23 00:03:33 +02:00
/* some basic validation checks */
2006-07-27 17:39:03 +02:00
if ( This - > cursorTexture ) {
2009-10-28 11:00:11 +01:00
struct wined3d_context * context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2007-08-06 16:27:08 +02:00
ENTER_GL ( ) ;
2006-07-27 17:39:03 +02:00
glDeleteTextures ( 1 , & This - > cursorTexture ) ;
LEAVE_GL ( ) ;
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2006-07-27 17:39:03 +02:00
This - > cursorTexture = 0 ;
}
2007-05-15 00:37:53 +02:00
if ( ( pSur - > currentDesc . Width = = 32 ) & & ( pSur - > currentDesc . Height = = 32 ) )
This - > haveHardwareCursor = TRUE ;
else
This - > haveHardwareCursor = FALSE ;
2006-07-23 00:03:33 +02:00
if ( pCursorBitmap ) {
2007-03-13 03:44:22 +01:00
WINED3DLOCKED_RECT rect ;
2006-07-23 00:03:33 +02:00
/* MSDN: Cursor must be A8R8G8B8 */
2009-09-25 13:31:49 +02:00
if ( pSur - > resource . format_desc - > format ! = WINED3DFMT_B8G8R8A8_UNORM )
2009-03-13 10:44:18 +01:00
{
2006-07-23 00:03:33 +02:00
ERR ( " (%p) : surface(%p) has an invalid format \n " , This , pCursorBitmap ) ;
return WINED3DERR_INVALIDCALL ;
}
/* MSDN: Cursor must be smaller than the display mode */
if ( pSur - > currentDesc . Width > This - > ddraw_width | |
pSur - > currentDesc . Height > This - > ddraw_height ) {
2006-10-01 05:20:10 +02:00
ERR ( " (%p) : Surface(%p) is %dx%d pixels, but screen res is %dx%d \n " , This , pSur , pSur - > currentDesc . Width , pSur - > currentDesc . Height , This - > ddraw_width , This - > ddraw_height ) ;
2006-07-23 00:03:33 +02:00
return WINED3DERR_INVALIDCALL ;
}
2007-05-15 00:37:53 +02:00
if ( ! This - > haveHardwareCursor ) {
/* TODO: MSDN: Cursor sizes must be a power of 2 */
2007-03-13 03:44:22 +01:00
2007-05-15 00:37:53 +02:00
/* Do not store the surface's pointer because the application may
* release it after setting the cursor image . Windows doesn ' t
* addref the set surface , so we can ' t do this either without
* creating circular refcount dependencies . Copy out the gl texture
* instead .
*/
This - > cursorWidth = pSur - > currentDesc . Width ;
This - > cursorHeight = pSur - > currentDesc . Height ;
if ( SUCCEEDED ( IWineD3DSurface_LockRect ( pCursorBitmap , & rect , NULL , WINED3DLOCK_READONLY ) ) )
{
2009-10-29 10:37:11 +01:00
const struct wined3d_gl_info * gl_info = & This - > adapter - > gl_info ;
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * format_desc = getFormatDescEntry ( WINED3DFMT_B8G8R8A8_UNORM , gl_info ) ;
2009-10-28 11:00:11 +01:00
struct wined3d_context * context ;
2009-02-03 09:36:07 +01:00
char * mem , * bits = rect . pBits ;
2010-03-19 13:19:51 +01:00
GLint intfmt = format_desc - > glInternal ;
GLint format = format_desc - > glFormat ;
GLint type = format_desc - > glType ;
2007-05-15 00:37:53 +02:00
INT height = This - > cursorHeight ;
INT width = This - > cursorWidth ;
2010-03-19 13:19:51 +01:00
INT bpp = format_desc - > byte_count ;
2009-08-17 09:39:07 +02:00
DWORD sampler ;
INT i ;
2007-05-15 00:37:53 +02:00
/* Reformat the texture memory (pitch and width can be
* different ) */
mem = HeapAlloc ( GetProcessHeap ( ) , 0 , width * height * bpp ) ;
for ( i = 0 ; i < height ; i + + )
memcpy ( & mem [ width * bpp * i ] , & bits [ rect . Pitch * i ] , width * bpp ) ;
IWineD3DSurface_UnlockRect ( pCursorBitmap ) ;
2009-06-25 10:24:58 +02:00
2009-10-28 11:00:11 +01:00
context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2009-06-25 10:24:58 +02:00
2007-05-15 00:37:53 +02:00
ENTER_GL ( ) ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ APPLE_CLIENT_STORAGE ] )
{
2007-05-15 00:37:53 +02:00
glPixelStorei ( GL_UNPACK_CLIENT_STORAGE_APPLE , GL_FALSE ) ;
checkGLcall ( " glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE) " ) ;
}
2007-04-19 22:52:11 +02:00
2007-05-15 00:37:53 +02:00
/* Make sure that a proper texture unit is selected */
2008-12-16 13:18:49 +01:00
GL_EXTCALL ( glActiveTextureARB ( GL_TEXTURE0_ARB ) ) ;
checkGLcall ( " glActiveTextureARB " ) ;
2008-07-15 23:54:44 +02:00
sampler = This - > rev_tex_unit_map [ 0 ] ;
2009-08-17 09:39:07 +02:00
if ( sampler ! = WINED3D_UNMAPPED_STAGE )
{
2008-07-15 23:54:44 +02:00
IWineD3DDeviceImpl_MarkStateDirty ( This , STATE_SAMPLER ( sampler ) ) ;
}
2007-05-15 00:37:53 +02:00
/* Create a new cursor texture */
glGenTextures ( 1 , & This - > cursorTexture ) ;
checkGLcall ( " glGenTextures " ) ;
glBindTexture ( GL_TEXTURE_2D , This - > cursorTexture ) ;
checkGLcall ( " glBindTexture " ) ;
/* Copy the bitmap memory into the cursor texture */
glTexImage2D ( GL_TEXTURE_2D , 0 , intfmt , width , height , 0 , format , type , mem ) ;
HeapFree ( GetProcessHeap ( ) , 0 , mem ) ;
checkGLcall ( " glTexImage2D " ) ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ APPLE_CLIENT_STORAGE ] )
{
2007-05-15 00:37:53 +02:00
glPixelStorei ( GL_UNPACK_CLIENT_STORAGE_APPLE , GL_TRUE ) ;
checkGLcall ( " glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE) " ) ;
}
2007-04-19 22:52:11 +02:00
2007-05-15 00:37:53 +02:00
LEAVE_GL ( ) ;
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2007-03-13 03:44:22 +01:00
}
2007-05-15 00:37:53 +02:00
else
{
FIXME ( " A cursor texture was not returned. \n " ) ;
This - > cursorTexture = 0 ;
2007-04-19 22:52:11 +02:00
}
2007-03-13 03:44:22 +01:00
}
else
{
2007-05-15 00:37:53 +02:00
/* Draw a hardware cursor */
ICONINFO cursorInfo ;
HCURSOR cursor ;
/* Create and clear maskBits because it is not needed for
* 32 - bit cursors . 32 x32 bits split into 32 - bit chunks = = 32
* chunks . */
DWORD * maskBits = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY ,
( pSur - > currentDesc . Width * pSur - > currentDesc . Height / 8 ) ) ;
IWineD3DSurface_LockRect ( pCursorBitmap , & lockedRect , NULL ,
WINED3DLOCK_NO_DIRTY_UPDATE |
WINED3DLOCK_READONLY
) ;
TRACE ( " width: %i height: %i \n " , pSur - > currentDesc . Width ,
pSur - > currentDesc . Height ) ;
cursorInfo . fIcon = FALSE ;
cursorInfo . xHotspot = XHotSpot ;
cursorInfo . yHotspot = YHotSpot ;
2009-10-23 10:26:11 +02:00
cursorInfo . hbmMask = CreateBitmap ( pSur - > currentDesc . Width , pSur - > currentDesc . Height ,
1 , 1 , maskBits ) ;
cursorInfo . hbmColor = CreateBitmap ( pSur - > currentDesc . Width , pSur - > currentDesc . Height ,
1 , 32 , lockedRect . pBits ) ;
2007-05-15 00:37:53 +02:00
IWineD3DSurface_UnlockRect ( pCursorBitmap ) ;
/* Create our cursor and clean up. */
cursor = CreateIconIndirect ( & cursorInfo ) ;
SetCursor ( cursor ) ;
if ( cursorInfo . hbmMask ) DeleteObject ( cursorInfo . hbmMask ) ;
if ( cursorInfo . hbmColor ) DeleteObject ( cursorInfo . hbmColor ) ;
if ( This - > hardwareCursor ) DestroyCursor ( This - > hardwareCursor ) ;
This - > hardwareCursor = cursor ;
HeapFree ( GetProcessHeap ( ) , 0 , maskBits ) ;
2007-03-13 03:44:22 +01:00
}
2005-03-02 13:16:10 +01:00
}
2005-07-13 16:15:54 +02:00
2005-03-02 13:16:10 +01:00
This - > xHotSpot = XHotSpot ;
This - > yHotSpot = YHotSpot ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static void WINAPI IWineD3DDeviceImpl_SetCursorPosition ( IWineD3DDevice * iface , int XScreenSpace , int YScreenSpace , DWORD Flags ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
TRACE ( " (%p) : SetPos to (%u,%u) \n " , This , XScreenSpace , YScreenSpace ) ;
2005-07-13 16:15:54 +02:00
2005-03-02 13:16:10 +01:00
This - > xScreenSpace = XScreenSpace ;
This - > yScreenSpace = YScreenSpace ;
2005-07-13 16:15:54 +02:00
2005-03-02 13:16:10 +01:00
return ;
}
2006-06-10 13:15:32 +02:00
static BOOL WINAPI IWineD3DDeviceImpl_ShowCursor ( IWineD3DDevice * iface , BOOL bShow ) {
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-08-09 22:23:31 +02:00
BOOL oldVisible = This - > bCursorVisible ;
2007-03-02 09:25:02 +01:00
POINT pt ;
2005-03-02 13:16:10 +01:00
TRACE ( " (%p) : visible(%d) \n " , This , bShow ) ;
2005-07-13 16:15:54 +02:00
2007-03-02 09:25:02 +01:00
/*
* When ShowCursor is first called it should make the cursor appear at the OS ' s last
* known cursor position . Because of this , some applications just repetitively call
* ShowCursor in order to update the cursor ' s position . This behavior is undocumented .
*/
GetCursorPos ( & pt ) ;
This - > xScreenSpace = pt . x ;
This - > yScreenSpace = pt . y ;
2005-07-13 16:15:54 +02:00
2007-05-15 00:37:53 +02:00
if ( This - > haveHardwareCursor ) {
This - > bCursorVisible = bShow ;
if ( bShow )
SetCursor ( This - > hardwareCursor ) ;
else
SetCursor ( NULL ) ;
}
else
{
if ( This - > cursorTexture )
This - > bCursorVisible = bShow ;
}
2006-08-09 22:23:31 +02:00
return oldVisible ;
2005-03-02 13:16:10 +01:00
}
2009-06-10 08:06:06 +02:00
static HRESULT WINAPI evict_managed_resource ( IWineD3DResource * resource , void * data ) {
TRACE ( " checking resource %p for eviction \n " , resource ) ;
if ( ( ( IWineD3DResourceImpl * ) resource ) - > resource . pool = = WINED3DPOOL_MANAGED ) {
TRACE ( " Evicting %p \n " , resource ) ;
IWineD3DResource_UnLoad ( resource ) ;
}
IWineD3DResource_Release ( resource ) ;
return S_OK ;
}
2005-03-02 13:16:10 +01:00
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_EvictManagedResources ( IWineD3DDevice * iface )
{
TRACE ( " iface %p. \n " , iface ) ;
2009-06-10 08:06:06 +02:00
IWineD3DDevice_EnumResources ( iface , evict_managed_resource , NULL ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2009-12-04 13:07:18 +01:00
static HRESULT updateSurfaceDesc ( IWineD3DSurfaceImpl * surface , const WINED3DPRESENT_PARAMETERS * pPresentationParameters )
2008-11-26 16:14:39 +01:00
{
2009-12-09 20:32:08 +01:00
IWineD3DDeviceImpl * device = surface - > resource . device ;
2009-10-29 10:37:11 +01:00
const struct wined3d_gl_info * gl_info = & device - > adapter - > gl_info ;
2007-02-13 20:21:48 +01:00
2006-12-08 16:13:15 +01:00
/* Reallocate proper memory for the front and back buffer and adjust their sizes */
if ( surface - > Flags & SFLAG_DIBSECTION ) {
/* Release the DC */
SelectObject ( surface - > hDC , surface - > dib . holdbitmap ) ;
DeleteDC ( surface - > hDC ) ;
/* Release the DIB section */
DeleteObject ( surface - > dib . DIBsection ) ;
surface - > dib . bitmap_data = NULL ;
surface - > resource . allocatedMemory = NULL ;
surface - > Flags & = ~ SFLAG_DIBSECTION ;
}
2007-02-15 22:36:50 +01:00
surface - > currentDesc . Width = pPresentationParameters - > BackBufferWidth ;
surface - > currentDesc . Height = pPresentationParameters - > BackBufferHeight ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_NON_POWER_OF_TWO ] | | gl_info - > supported [ ARB_TEXTURE_RECTANGLE ]
| | gl_info - > supported [ WINE_NORMALIZED_TEXRECT ] )
{
2007-02-15 22:36:50 +01:00
surface - > pow2Width = pPresentationParameters - > BackBufferWidth ;
surface - > pow2Height = pPresentationParameters - > BackBufferHeight ;
2006-12-08 16:13:15 +01:00
} else {
surface - > pow2Width = surface - > pow2Height = 1 ;
2007-02-15 22:36:50 +01:00
while ( surface - > pow2Width < pPresentationParameters - > BackBufferWidth ) surface - > pow2Width < < = 1 ;
while ( surface - > pow2Height < pPresentationParameters - > BackBufferHeight ) surface - > pow2Height < < = 1 ;
2006-12-08 16:13:15 +01:00
}
2008-01-27 21:26:07 +01:00
2009-07-10 10:20:13 +02:00
if ( surface - > texture_name )
{
2009-10-29 10:37:11 +01:00
struct wined3d_context * context = context_acquire ( device , NULL , CTXUSAGE_RESOURCELOAD ) ;
2007-08-06 16:27:08 +02:00
ENTER_GL ( ) ;
2009-07-10 10:20:13 +02:00
glDeleteTextures ( 1 , & surface - > texture_name ) ;
2006-12-08 16:13:15 +01:00
LEAVE_GL ( ) ;
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2009-07-10 10:20:13 +02:00
surface - > texture_name = 0 ;
2007-03-31 23:02:37 +02:00
surface - > Flags & = ~ SFLAG_CLIENT ;
2006-12-08 16:13:15 +01:00
}
2007-02-15 22:36:50 +01:00
if ( surface - > pow2Width ! = pPresentationParameters - > BackBufferWidth | |
surface - > pow2Height ! = pPresentationParameters - > BackBufferHeight ) {
2006-12-08 16:13:15 +01:00
surface - > Flags | = SFLAG_NONPOW2 ;
} else {
surface - > Flags & = ~ SFLAG_NONPOW2 ;
}
2008-03-23 16:14:05 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , surface - > resource . heapMemory ) ;
surface - > resource . allocatedMemory = NULL ;
surface - > resource . heapMemory = NULL ;
2006-12-08 16:13:15 +01:00
surface - > resource . size = IWineD3DSurface_GetPitch ( ( IWineD3DSurface * ) surface ) * surface - > pow2Width ;
2009-12-04 13:07:18 +01:00
/* Put all surfaces into sysmem - the drawable might disappear if the backbuffer was rendered
* to a FBO */
2010-04-28 00:08:48 +02:00
if ( ! surface_init_sysmem ( surface ) )
2009-12-04 13:07:18 +01:00
{
return E_OUTOFMEMORY ;
2008-06-02 21:12:54 +02:00
}
2009-12-04 13:07:18 +01:00
return WINED3D_OK ;
2006-12-08 16:13:15 +01:00
}
2008-01-08 22:34:43 +01:00
static HRESULT WINAPI reset_unload_resources ( IWineD3DResource * resource , void * data ) {
TRACE ( " Unloading resource %p \n " , resource ) ;
IWineD3DResource_UnLoad ( resource ) ;
IWineD3DResource_Release ( resource ) ;
return S_OK ;
}
2008-11-26 16:14:39 +01:00
static BOOL is_display_mode_supported ( IWineD3DDeviceImpl * This , const WINED3DPRESENT_PARAMETERS * pp )
{
2008-02-06 20:16:13 +01:00
UINT i , count ;
WINED3DDISPLAYMODE m ;
HRESULT hr ;
/* All Windowed modes are supported, as is leaving the current mode */
if ( pp - > Windowed ) return TRUE ;
if ( ! pp - > BackBufferWidth ) return TRUE ;
if ( ! pp - > BackBufferHeight ) return TRUE ;
2009-12-07 20:20:02 +01:00
count = IWineD3D_GetAdapterModeCount ( This - > wined3d , This - > adapter - > ordinal , WINED3DFMT_UNKNOWN ) ;
2008-02-06 20:16:13 +01:00
for ( i = 0 ; i < count ; i + + ) {
memset ( & m , 0 , sizeof ( m ) ) ;
2009-12-07 20:20:02 +01:00
hr = IWineD3D_EnumAdapterModes ( This - > wined3d , This - > adapter - > ordinal , WINED3DFMT_UNKNOWN , i , & m ) ;
2008-02-06 20:16:13 +01:00
if ( FAILED ( hr ) ) {
ERR ( " EnumAdapterModes failed \n " ) ;
}
if ( m . Width = = pp - > BackBufferWidth & & m . Height = = pp - > BackBufferHeight ) {
/* Mode found, it is supported */
return TRUE ;
}
}
/* Mode not found -> not supported */
return FALSE ;
}
2010-04-04 19:51:39 +02:00
static void delete_opengl_contexts ( IWineD3DDevice * iface , IWineD3DSwapChainImpl * swapchain )
{
2008-07-29 19:09:34 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-09-23 10:05:55 +02:00
const struct wined3d_gl_info * gl_info ;
2009-10-28 11:00:11 +01:00
struct wined3d_context * context ;
2008-07-29 19:09:34 +02:00
IWineD3DBaseShaderImpl * shader ;
2009-10-28 11:00:11 +01:00
context = context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
2009-09-23 10:05:55 +02:00
gl_info = context - > gl_info ;
2009-06-25 10:24:54 +02:00
2008-07-29 19:09:34 +02:00
IWineD3DDevice_EnumResources ( iface , reset_unload_resources , NULL ) ;
LIST_FOR_EACH_ENTRY ( shader , & This - > shaders , IWineD3DBaseShaderImpl , baseShader . shader_list_entry ) {
This - > shader_backend - > shader_destroy ( ( IWineD3DBaseShader * ) shader ) ;
}
ENTER_GL ( ) ;
if ( This - > depth_blt_texture ) {
glDeleteTextures ( 1 , & This - > depth_blt_texture ) ;
This - > depth_blt_texture = 0 ;
}
if ( This - > depth_blt_rb ) {
2009-09-23 10:05:55 +02:00
gl_info - > fbo_ops . glDeleteRenderbuffers ( 1 , & This - > depth_blt_rb ) ;
2008-07-29 19:09:34 +02:00
This - > depth_blt_rb = 0 ;
This - > depth_blt_rb_w = 0 ;
This - > depth_blt_rb_h = 0 ;
}
2008-10-19 01:21:06 +02:00
LEAVE_GL ( ) ;
2008-08-01 20:21:10 +02:00
This - > blitter - > free_private ( iface ) ;
2008-07-29 19:09:34 +02:00
This - > frag_pipe - > free_private ( iface ) ;
This - > shader_backend - > shader_free_private ( iface ) ;
2009-12-17 19:14:34 +01:00
destroy_dummy_textures ( This , gl_info ) ;
2008-07-29 19:09:34 +02:00
2009-10-28 11:00:11 +01:00
context_release ( context ) ;
2009-10-28 11:00:14 +01:00
while ( This - > numContexts )
{
context_destroy ( This , This - > contexts [ 0 ] ) ;
2008-07-29 19:09:34 +02:00
}
HeapFree ( GetProcessHeap ( ) , 0 , swapchain - > context ) ;
swapchain - > context = NULL ;
swapchain - > num_contexts = 0 ;
}
2010-04-04 19:51:39 +02:00
static HRESULT create_primary_opengl_context ( IWineD3DDevice * iface , IWineD3DSwapChainImpl * swapchain )
{
2008-07-29 19:09:34 +02:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2009-12-17 19:14:35 +01:00
struct wined3d_context * context ;
2008-07-29 19:09:34 +02:00
HRESULT hr ;
IWineD3DSurfaceImpl * target ;
/* Recreate the primary swapchain's context */
swapchain - > context = HeapAlloc ( GetProcessHeap ( ) , 0 , sizeof ( * swapchain - > context ) ) ;
2009-12-17 19:14:35 +01:00
if ( ! swapchain - > context )
{
ERR ( " Failed to allocate memory for swapchain context array. \n " ) ;
return E_OUTOFMEMORY ;
2008-07-29 19:09:34 +02:00
}
2010-04-26 21:33:01 +02:00
target = swapchain - > back_buffers ? swapchain - > back_buffers [ 0 ] : swapchain - > front_buffer ;
2010-03-28 16:25:04 +02:00
if ( ! ( context = context_create ( swapchain , target , swapchain - > ds_format ) ) )
2009-12-17 19:14:35 +01:00
{
WARN ( " Failed to create context. \n " ) ;
HeapFree ( GetProcessHeap ( ) , 0 , swapchain - > context ) ;
return E_FAIL ;
}
2008-07-29 19:09:34 +02:00
2009-12-17 19:14:35 +01:00
swapchain - > context [ 0 ] = context ;
swapchain - > num_contexts = 1 ;
create_dummy_textures ( This ) ;
context_release ( context ) ;
2009-10-28 11:00:12 +01:00
2008-07-29 19:09:34 +02:00
hr = This - > shader_backend - > shader_alloc_private ( iface ) ;
2009-12-17 19:14:35 +01:00
if ( FAILED ( hr ) )
{
ERR ( " Failed to allocate shader private data, hr %#x. \n " , hr ) ;
goto err ;
2008-07-29 19:09:34 +02:00
}
2009-12-17 19:14:35 +01:00
2008-07-29 19:09:34 +02:00
hr = This - > frag_pipe - > alloc_private ( iface ) ;
2009-12-17 19:14:35 +01:00
if ( FAILED ( hr ) )
{
ERR ( " Failed to allocate fragment pipe private data, hr %#x. \n " , hr ) ;
This - > shader_backend - > shader_free_private ( iface ) ;
goto err ;
2008-08-01 20:21:10 +02:00
}
2009-12-17 19:14:35 +01:00
2008-08-01 20:21:10 +02:00
hr = This - > blitter - > alloc_private ( iface ) ;
2009-12-17 19:14:35 +01:00
if ( FAILED ( hr ) )
{
ERR ( " Failed to allocate blitter private data, hr %#x. \n " , hr ) ;
This - > frag_pipe - > free_private ( iface ) ;
This - > shader_backend - > shader_free_private ( iface ) ;
goto err ;
2008-07-29 19:09:34 +02:00
}
return WINED3D_OK ;
2008-08-01 20:21:10 +02:00
2009-12-17 19:14:35 +01:00
err :
context_acquire ( This , NULL , CTXUSAGE_RESOURCELOAD ) ;
destroy_dummy_textures ( This , context - > gl_info ) ;
context_release ( context ) ;
context_destroy ( This , context ) ;
HeapFree ( GetProcessHeap ( ) , 0 , swapchain - > context ) ;
swapchain - > num_contexts = 0 ;
2008-08-01 20:21:10 +02:00
return hr ;
2008-07-29 19:09:34 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_Reset ( IWineD3DDevice * iface , WINED3DPRESENT_PARAMETERS * pPresentationParameters ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-12-08 16:13:15 +01:00
IWineD3DSwapChainImpl * swapchain ;
HRESULT hr ;
BOOL DisplayModeChanged = FALSE ;
WINED3DDISPLAYMODE mode ;
TRACE ( " (%p) \n " , This ) ;
hr = IWineD3DDevice_GetSwapChain ( iface , 0 , ( IWineD3DSwapChain * * ) & swapchain ) ;
if ( FAILED ( hr ) ) {
ERR ( " Failed to get the first implicit swapchain \n " ) ;
return hr ;
}
2008-02-06 20:16:13 +01:00
if ( ! is_display_mode_supported ( This , pPresentationParameters ) ) {
WARN ( " Rejecting Reset() call because the requested display mode is not supported \n " ) ;
WARN ( " Requested mode: %d, %d \n " , pPresentationParameters - > BackBufferWidth ,
pPresentationParameters - > BackBufferHeight ) ;
2009-03-31 09:38:14 +02:00
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
2008-02-06 20:16:13 +01:00
return WINED3DERR_INVALIDCALL ;
}
2006-12-08 16:13:15 +01:00
/* Is it necessary to recreate the gl context? Actually every setting can be changed
* on an existing gl context , so there ' s no real need for recreation .
*
* TODO : Figure out how Reset influences resources in D3DPOOL_DEFAULT , D3DPOOL_SYSTEMMEMORY and D3DPOOL_MANAGED
*
* TODO : Figure out what happens to explicit swapchains , or if we have more than one implicit swapchain
*/
TRACE ( " New params: \n " ) ;
2007-02-15 22:36:50 +01:00
TRACE ( " BackBufferWidth = %d \n " , pPresentationParameters - > BackBufferWidth ) ;
TRACE ( " BackBufferHeight = %d \n " , pPresentationParameters - > BackBufferHeight ) ;
TRACE ( " BackBufferFormat = %s \n " , debug_d3dformat ( pPresentationParameters - > BackBufferFormat ) ) ;
TRACE ( " BackBufferCount = %d \n " , pPresentationParameters - > BackBufferCount ) ;
TRACE ( " MultiSampleType = %d \n " , pPresentationParameters - > MultiSampleType ) ;
TRACE ( " MultiSampleQuality = %d \n " , pPresentationParameters - > MultiSampleQuality ) ;
TRACE ( " SwapEffect = %d \n " , pPresentationParameters - > SwapEffect ) ;
TRACE ( " hDeviceWindow = %p \n " , pPresentationParameters - > hDeviceWindow ) ;
TRACE ( " Windowed = %s \n " , pPresentationParameters - > Windowed ? " true " : " false " ) ;
TRACE ( " EnableAutoDepthStencil = %s \n " , pPresentationParameters - > EnableAutoDepthStencil ? " true " : " false " ) ;
TRACE ( " Flags = %08x \n " , pPresentationParameters - > Flags ) ;
TRACE ( " FullScreen_RefreshRateInHz = %d \n " , pPresentationParameters - > FullScreen_RefreshRateInHz ) ;
TRACE ( " PresentationInterval = %d \n " , pPresentationParameters - > PresentationInterval ) ;
2006-12-08 16:13:15 +01:00
/* No special treatment of these parameters. Just store them */
2007-02-15 22:36:50 +01:00
swapchain - > presentParms . SwapEffect = pPresentationParameters - > SwapEffect ;
swapchain - > presentParms . Flags = pPresentationParameters - > Flags ;
swapchain - > presentParms . PresentationInterval = pPresentationParameters - > PresentationInterval ;
swapchain - > presentParms . FullScreen_RefreshRateInHz = pPresentationParameters - > FullScreen_RefreshRateInHz ;
2006-12-08 16:13:15 +01:00
/* What to do about these? */
2007-02-15 22:36:50 +01:00
if ( pPresentationParameters - > BackBufferCount ! = 0 & &
pPresentationParameters - > BackBufferCount ! = swapchain - > presentParms . BackBufferCount ) {
2006-12-08 16:13:15 +01:00
ERR ( " Cannot change the back buffer count yet \n " ) ;
}
2007-02-15 22:36:50 +01:00
if ( pPresentationParameters - > BackBufferFormat ! = WINED3DFMT_UNKNOWN & &
pPresentationParameters - > BackBufferFormat ! = swapchain - > presentParms . BackBufferFormat ) {
2006-12-08 16:13:15 +01:00
ERR ( " Cannot change the back buffer format yet \n " ) ;
}
2007-02-15 22:36:50 +01:00
if ( pPresentationParameters - > hDeviceWindow ! = NULL & &
pPresentationParameters - > hDeviceWindow ! = swapchain - > presentParms . hDeviceWindow ) {
2006-12-08 16:13:15 +01:00
ERR ( " Cannot change the device window yet \n " ) ;
}
2010-04-19 20:47:00 +02:00
if ( pPresentationParameters - > EnableAutoDepthStencil & & ! This - > auto_depth_stencil )
{
2009-04-23 08:33:21 +02:00
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 ,
2010-04-19 20:47:00 +02:00
( IWineD3DSurface * * ) & This - > auto_depth_stencil ) ;
2009-04-23 08:33:21 +02:00
if ( FAILED ( hrc ) ) {
ERR ( " Failed to create the depth stencil buffer \n " ) ;
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
return WINED3DERR_INVALIDCALL ;
}
2006-12-08 16:13:15 +01:00
}
2008-01-08 22:34:43 +01:00
2010-04-20 22:38:41 +02:00
if ( This - > onscreen_depth_stencil )
{
IWineD3DSurface_Release ( ( IWineD3DSurface * ) This - > onscreen_depth_stencil ) ;
This - > onscreen_depth_stencil = NULL ;
}
2008-09-10 11:08:58 +02:00
/* Reset the depth stencil */
if ( pPresentationParameters - > EnableAutoDepthStencil )
2010-04-19 20:47:00 +02:00
IWineD3DDevice_SetDepthStencilSurface ( iface , ( IWineD3DSurface * ) This - > auto_depth_stencil ) ;
2008-09-10 11:08:58 +02:00
else
IWineD3DDevice_SetDepthStencilSurface ( iface , NULL ) ;
2009-09-25 13:31:50 +02:00
TRACE ( " Resetting stateblock \n " ) ;
IWineD3DStateBlock_Release ( ( IWineD3DStateBlock * ) This - > updateStateBlock ) ;
IWineD3DStateBlock_Release ( ( IWineD3DStateBlock * ) This - > stateBlock ) ;
2010-04-04 19:51:39 +02:00
delete_opengl_contexts ( iface , swapchain ) ;
2008-02-05 00:05:26 +01:00
2008-07-29 19:09:34 +02:00
if ( pPresentationParameters - > Windowed ) {
2006-12-08 16:13:15 +01:00
mode . Width = swapchain - > orig_width ;
mode . Height = swapchain - > orig_height ;
mode . RefreshRate = 0 ;
mode . Format = swapchain - > presentParms . BackBufferFormat ;
} else {
2007-02-15 22:36:50 +01:00
mode . Width = pPresentationParameters - > BackBufferWidth ;
mode . Height = pPresentationParameters - > BackBufferHeight ;
mode . RefreshRate = pPresentationParameters - > FullScreen_RefreshRateInHz ;
2006-12-08 16:13:15 +01:00
mode . Format = swapchain - > presentParms . BackBufferFormat ;
}
/* Should Width == 800 && Height == 0 set 800x600? */
2007-02-15 22:36:50 +01:00
if ( pPresentationParameters - > BackBufferWidth ! = 0 & & pPresentationParameters - > BackBufferHeight ! = 0 & &
( pPresentationParameters - > BackBufferWidth ! = swapchain - > presentParms . BackBufferWidth | |
pPresentationParameters - > BackBufferHeight ! = swapchain - > presentParms . BackBufferHeight ) )
2006-12-08 16:13:15 +01:00
{
2008-11-20 23:13:48 +01:00
UINT i ;
2006-12-08 16:13:15 +01:00
2007-02-15 22:36:50 +01:00
if ( ! pPresentationParameters - > Windowed ) {
2006-12-08 16:13:15 +01:00
DisplayModeChanged = TRUE ;
}
2007-02-15 22:36:50 +01:00
swapchain - > presentParms . BackBufferWidth = pPresentationParameters - > BackBufferWidth ;
swapchain - > presentParms . BackBufferHeight = pPresentationParameters - > BackBufferHeight ;
2006-12-08 16:13:15 +01:00
2010-04-26 21:33:00 +02:00
hr = updateSurfaceDesc ( swapchain - > front_buffer , pPresentationParameters ) ;
2009-12-04 13:07:18 +01:00
if ( FAILED ( hr ) )
{
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
return hr ;
}
2010-04-26 21:33:01 +02:00
for ( i = 0 ; i < swapchain - > presentParms . BackBufferCount ; + + i )
{
hr = updateSurfaceDesc ( swapchain - > back_buffers [ i ] , pPresentationParameters ) ;
2009-12-04 13:07:18 +01:00
if ( FAILED ( hr ) )
{
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
return hr ;
}
2006-12-08 16:13:15 +01:00
}
2010-04-19 20:47:00 +02:00
if ( This - > auto_depth_stencil )
{
hr = updateSurfaceDesc ( This - > auto_depth_stencil , pPresentationParameters ) ;
2009-12-04 13:07:18 +01:00
if ( FAILED ( hr ) )
{
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
return hr ;
}
2008-01-25 18:04:05 +01:00
}
2006-12-08 16:13:15 +01:00
}
2010-03-15 21:07:29 +01:00
if ( ! pPresentationParameters - > Windowed ! = ! swapchain - > presentParms . Windowed
| | DisplayModeChanged )
{
2008-03-10 22:24:13 +01:00
IWineD3DDevice_SetDisplayMode ( iface , 0 , & mode ) ;
2008-08-04 21:11:22 +02:00
2010-03-15 21:07:28 +01:00
if ( ! pPresentationParameters - > Windowed )
{
2008-08-04 21:11:22 +02:00
if ( swapchain - > presentParms . Windowed ) {
/* switch from windowed to fs */
2009-12-10 21:41:55 +01:00
swapchain_setup_fullscreen_window ( swapchain , pPresentationParameters - > BackBufferWidth ,
pPresentationParameters - > BackBufferHeight ) ;
2008-08-04 21:11:22 +02:00
} else {
/* Fullscreen -> fullscreen mode change */
2010-03-15 21:07:30 +01:00
MoveWindow ( swapchain - > device_window , 0 , 0 ,
2008-08-04 21:16:49 +02:00
pPresentationParameters - > BackBufferWidth , pPresentationParameters - > BackBufferHeight ,
TRUE ) ;
2008-08-04 21:11:22 +02:00
}
2010-03-15 21:07:28 +01:00
}
else if ( ! swapchain - > presentParms . Windowed )
{
2008-08-04 21:11:22 +02:00
/* Fullscreen -> windowed switch */
2009-12-10 21:41:56 +01:00
swapchain_restore_fullscreen_window ( swapchain ) ;
2008-08-04 21:11:22 +02:00
}
swapchain - > presentParms . Windowed = pPresentationParameters - > Windowed ;
2008-02-06 22:12:06 +01:00
} else if ( ! pPresentationParameters - > Windowed ) {
DWORD style = This - > style , exStyle = This - > exStyle ;
/* If we're in fullscreen, and the mode wasn't changed, we have to get the window back into
* the right position . Some applications ( Battlefield 2 , Guild Wars ) move it and then call
* Reset to clear up their mess . Guild Wars also loses the device during that .
*/
This - > style = 0 ;
This - > exStyle = 0 ;
2009-12-10 21:41:55 +01:00
swapchain_setup_fullscreen_window ( swapchain , pPresentationParameters - > BackBufferWidth ,
pPresentationParameters - > BackBufferHeight ) ;
2008-02-06 22:12:06 +01:00
This - > style = style ;
This - > exStyle = exStyle ;
2006-12-08 16:13:15 +01:00
}
2008-12-19 19:21:55 +01:00
/* Note: No parent needed for initial internal stateblock */
hr = IWineD3DDevice_CreateStateBlock ( iface , WINED3DSBT_INIT , ( IWineD3DStateBlock * * ) & This - > stateBlock , NULL ) ;
if ( FAILED ( hr ) ) ERR ( " Resetting the stateblock failed with error 0x%08x \n " , hr ) ;
else TRACE ( " Created stateblock %p \n " , This - > stateBlock ) ;
This - > updateStateBlock = This - > stateBlock ;
IWineD3DStateBlock_AddRef ( ( IWineD3DStateBlock * ) This - > updateStateBlock ) ;
2008-02-05 21:51:53 +01:00
hr = IWineD3DStateBlock_InitStartupStateBlock ( ( IWineD3DStateBlock * ) This - > stateBlock ) ;
if ( FAILED ( hr ) ) {
ERR ( " Resetting the stateblock failed with error 0x%08x \n " , hr ) ;
}
2008-03-18 19:31:24 +01:00
2009-12-06 18:08:39 +01:00
if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO )
{
RECT client_rect ;
GetClientRect ( swapchain - > win_handle , & client_rect ) ;
2009-12-15 20:16:19 +01:00
if ( ! swapchain - > presentParms . BackBufferCount )
{
TRACE ( " Single buffered rendering \n " ) ;
swapchain - > render_to_fbo = FALSE ;
}
else if ( swapchain - > presentParms . BackBufferWidth ! = client_rect . right | |
swapchain - > presentParms . BackBufferHeight ! = client_rect . bottom )
2009-12-06 18:08:39 +01:00
{
TRACE ( " Rendering to FBO. Backbuffer %ux%u, window %ux%u \n " ,
swapchain - > presentParms . BackBufferWidth ,
swapchain - > presentParms . BackBufferHeight ,
client_rect . right , client_rect . bottom ) ;
swapchain - > render_to_fbo = TRUE ;
}
else
{
TRACE ( " Rendering directly to GL_BACK \n " ) ;
swapchain - > render_to_fbo = FALSE ;
}
}
2010-04-04 19:51:39 +02:00
hr = create_primary_opengl_context ( iface , swapchain ) ;
2008-07-29 19:09:34 +02:00
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapchain ) ;
2008-03-18 19:31:24 +01:00
2008-02-05 00:05:26 +01:00
/* All done. There is no need to reload resources or shaders, this will happen automatically on the
* first use
*/
2008-07-29 19:09:34 +02:00
return hr ;
2005-03-02 13:16:10 +01:00
}
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_SetDialogBoxMode ( IWineD3DDevice * iface , BOOL enable_dialogs )
{
TRACE ( " iface %p, enable_dialogs %#x. \n " , iface , enable_dialogs ) ;
if ( ! enable_dialogs ) FIXME ( " Dialogs cannot be disabled yet. \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetCreationParameters ( IWineD3DDevice * iface , WINED3DDEVICE_CREATION_PARAMETERS * pParameters ) {
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2006-03-07 00:29:45 +01:00
TRACE ( " (%p) : pParameters %p \n " , This , pParameters ) ;
2005-07-13 16:15:54 +02:00
2006-03-07 00:29:45 +01:00
* pParameters = This - > createParms ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static void WINAPI IWineD3DDeviceImpl_SetGammaRamp ( IWineD3DDevice * iface , UINT iSwapChain , DWORD Flags , CONST WINED3DGAMMARAMP * pRamp ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChain * swapchain ;
TRACE ( " Relaying to swapchain \n " ) ;
2008-04-29 22:29:45 +02:00
if ( IWineD3DDeviceImpl_GetSwapChain ( iface , iSwapChain , & swapchain ) = = WINED3D_OK ) {
2008-11-25 11:57:39 +01:00
IWineD3DSwapChain_SetGammaRamp ( swapchain , Flags , pRamp ) ;
2006-11-30 13:33:11 +01:00
IWineD3DSwapChain_Release ( swapchain ) ;
2005-06-23 13:05:24 +02:00
}
2005-03-02 13:16:10 +01:00
}
2006-06-10 13:15:32 +02:00
static void WINAPI IWineD3DDeviceImpl_GetGammaRamp ( IWineD3DDevice * iface , UINT iSwapChain , WINED3DGAMMARAMP * pRamp ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChain * swapchain ;
2005-03-02 13:16:10 +01:00
2005-06-23 13:05:24 +02:00
TRACE ( " Relaying to swapchain \n " ) ;
2008-04-29 22:29:45 +02:00
if ( IWineD3DDeviceImpl_GetSwapChain ( iface , iSwapChain , & swapchain ) = = WINED3D_OK ) {
IWineD3DSwapChain_GetGammaRamp ( swapchain , pRamp ) ;
2006-11-30 13:33:11 +01:00
IWineD3DSwapChain_Release ( swapchain ) ;
2005-06-23 13:05:24 +02:00
}
2004-10-07 06:22:21 +02:00
}
2005-07-26 12:34:15 +02:00
/** ********************************************************
* Notification functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** This function must be called in the release of a resource when ref == 0,
* the contents of resource must still be correct ,
2008-01-09 20:37:05 +01:00
* any handles to other resource held by the caller must be closed
2005-07-26 12:34:15 +02:00
* ( e . g . a texture should release all held surfaces because telling the device that it ' s been released . )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-05-29 09:13:21 +02:00
void device_resource_add ( IWineD3DDeviceImpl * This , IWineD3DResource * resource )
{
TRACE ( " (%p) : Adding resource %p \n " , This , resource ) ;
2005-07-26 12:34:15 +02:00
2007-11-16 20:28:45 +01:00
list_add_head ( & This - > resources , & ( ( IWineD3DResourceImpl * ) resource ) - > resource . resource_list_entry ) ;
2005-07-26 12:34:15 +02:00
}
2009-05-29 09:13:21 +02:00
static void device_resource_remove ( IWineD3DDeviceImpl * This , IWineD3DResource * resource )
{
2007-11-16 20:28:45 +01:00
TRACE ( " (%p) : Removing resource %p \n " , This , resource ) ;
2005-07-26 12:34:15 +02:00
2007-11-16 20:28:45 +01:00
list_remove ( & ( ( IWineD3DResourceImpl * ) resource ) - > resource . resource_list_entry ) ;
2005-07-26 12:34:15 +02:00
}
2009-05-29 09:13:21 +02:00
void device_resource_released ( IWineD3DDeviceImpl * This , IWineD3DResource * resource )
{
2008-09-18 14:57:53 +02:00
WINED3DRESOURCETYPE type = IWineD3DResource_GetType ( resource ) ;
2005-07-26 12:34:15 +02:00
int counter ;
TRACE ( " (%p) : resource %p \n " , This , resource ) ;
2008-09-18 14:57:53 +02:00
2009-05-29 09:13:21 +02:00
context_resource_released ( ( IWineD3DDevice * ) This , resource , type ) ;
2008-09-18 14:57:53 +02:00
switch ( type ) {
2005-07-26 12:34:15 +02:00
/* TODO: check front and back buffers, rendertargets etc.. possibly swapchains? */
2007-04-09 01:53:27 +02:00
case WINED3DRTYPE_SURFACE : {
unsigned int i ;
2009-06-25 10:24:56 +02:00
if ( This - > d3d_initialized )
{
2009-10-29 10:37:10 +01:00
for ( i = 0 ; i < This - > adapter - > gl_info . limits . buffers ; + + i )
2009-10-22 10:09:54 +02:00
{
2010-04-19 20:46:59 +02:00
if ( This - > render_targets [ i ] = = ( IWineD3DSurfaceImpl * ) resource )
2008-08-21 18:34:55 +02:00
This - > render_targets [ i ] = NULL ;
2007-07-18 23:13:58 +02:00
}
2010-04-19 20:47:01 +02:00
if ( This - > depth_stencil = = ( IWineD3DSurfaceImpl * ) resource )
This - > depth_stencil = NULL ;
2007-04-09 01:53:27 +02:00
}
break ;
}
2006-03-09 23:21:16 +01:00
case WINED3DRTYPE_TEXTURE :
case WINED3DRTYPE_CUBETEXTURE :
case WINED3DRTYPE_VOLUMETEXTURE :
2007-06-25 22:45:40 +02:00
for ( counter = 0 ; counter < MAX_COMBINED_SAMPLERS ; counter + + ) {
2005-07-26 12:34:15 +02:00
if ( This - > stateBlock ! = NULL & & This - > stateBlock - > textures [ counter ] = = ( IWineD3DBaseTexture * ) resource ) {
2005-12-15 10:25:47 +01:00
WARN ( " Texture being released is still by a stateblock, Stage = %u Texture = %p \n " , counter , resource ) ;
2005-07-26 12:34:15 +02:00
This - > stateBlock - > textures [ counter ] = NULL ;
}
if ( This - > updateStateBlock ! = This - > stateBlock ) {
if ( This - > updateStateBlock - > textures [ counter ] = = ( IWineD3DBaseTexture * ) resource ) {
2005-12-15 10:25:47 +01:00
WARN ( " Texture being released is still by a stateblock, Stage = %u Texture = %p \n " , counter , resource ) ;
2005-07-26 12:34:15 +02:00
This - > updateStateBlock - > textures [ counter ] = NULL ;
}
}
}
break ;
2006-03-09 23:21:16 +01:00
case WINED3DRTYPE_VOLUME :
2005-07-26 12:34:15 +02:00
/* TODO: nothing really? */
break ;
2009-04-06 16:44:00 +02:00
case WINED3DRTYPE_BUFFER :
2005-07-26 12:34:15 +02:00
{
int streamNumber ;
TRACE ( " Cleaning up stream pointers \n " ) ;
for ( streamNumber = 0 ; streamNumber < MAX_STREAMS ; streamNumber + + ) {
/* FINDOUT: should a warn be generated if were recording and updateStateBlock->streamSource is lost?
FINDOUT : should changes . streamSource [ StreamNumber ] be set ?
*/
if ( This - > updateStateBlock ! = NULL ) { /* ==NULL when device is being destroyed */
if ( ( IWineD3DResource * ) This - > updateStateBlock - > streamSource [ streamNumber ] = = resource ) {
2006-09-25 11:54:14 +02:00
FIXME ( " Vertex buffer released while bound to a state block, stream %d \n " , streamNumber ) ;
2005-07-26 12:34:15 +02:00
This - > updateStateBlock - > streamSource [ streamNumber ] = 0 ;
/* Set changed flag? */
}
}
2005-11-23 20:14:43 +01:00
if ( This - > stateBlock ! = NULL ) { /* only happens if there is an error in the application, or on reset/release (because we don't manage internal tracking properly) */
2005-07-26 12:34:15 +02:00
if ( ( IWineD3DResource * ) This - > stateBlock - > streamSource [ streamNumber ] = = resource ) {
2006-09-25 11:54:14 +02:00
TRACE ( " Vertex buffer released while bound to a state block, stream %d \n " , streamNumber ) ;
2005-07-26 12:34:15 +02:00
This - > stateBlock - > streamSource [ streamNumber ] = 0 ;
}
}
}
2009-04-06 16:44:00 +02:00
if ( This - > updateStateBlock ! = NULL ) { /* ==NULL when device is being destroyed */
2009-04-06 16:46:12 +02:00
if ( This - > updateStateBlock - > pIndexData = = ( IWineD3DBuffer * ) resource ) {
2009-04-06 16:44:00 +02:00
This - > updateStateBlock - > pIndexData = NULL ;
}
2005-07-26 12:34:15 +02:00
}
2009-04-06 16:44:00 +02:00
if ( This - > stateBlock ! = NULL ) { /* ==NULL when device is being destroyed */
2009-04-06 16:46:12 +02:00
if ( This - > stateBlock - > pIndexData = = ( IWineD3DBuffer * ) resource ) {
2009-04-06 16:44:00 +02:00
This - > stateBlock - > pIndexData = NULL ;
}
2005-07-26 12:34:15 +02:00
}
}
break ;
2009-02-23 09:16:02 +01:00
2005-07-26 12:34:15 +02:00
default :
2005-11-10 13:14:56 +01:00
FIXME ( " (%p) unknown resource type %p %u \n " , This , resource , IWineD3DResource_GetType ( resource ) ) ;
2005-07-26 12:34:15 +02:00
break ;
}
2008-01-09 20:37:05 +01:00
/* Remove the resource from the resourceStore */
2009-05-29 09:13:21 +02:00
device_resource_remove ( This , resource ) ;
2005-07-26 12:34:15 +02:00
TRACE ( " Resource released \n " ) ;
}
2008-01-11 15:38:54 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_EnumResources ( IWineD3DDevice * iface , D3DCB_ENUMRESOURCES pCallback , void * pData ) {
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DResourceImpl * resource , * cursor ;
HRESULT ret ;
TRACE ( " (%p)->(%p,%p) \n " , This , pCallback , pData ) ;
LIST_FOR_EACH_ENTRY_SAFE ( resource , cursor , & This - > resources , IWineD3DResourceImpl , resource . resource_list_entry ) {
TRACE ( " enumerating resource %p \n " , resource ) ;
IWineD3DResource_AddRef ( ( IWineD3DResource * ) resource ) ;
ret = pCallback ( ( IWineD3DResource * ) resource , pData ) ;
if ( ret = = S_FALSE ) {
TRACE ( " Canceling enumeration \n " ) ;
break ;
}
}
return WINED3D_OK ;
}
2010-03-16 19:02:21 +01:00
static HRESULT WINAPI IWineD3DDeviceImpl_GetSurfaceFromDC ( IWineD3DDevice * iface , HDC dc , IWineD3DSurface * * surface )
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
IWineD3DResourceImpl * resource ;
LIST_FOR_EACH_ENTRY ( resource , & This - > resources , IWineD3DResourceImpl , resource . resource_list_entry )
{
WINED3DRESOURCETYPE type = IWineD3DResource_GetType ( ( IWineD3DResource * ) resource ) ;
if ( type = = WINED3DRTYPE_SURFACE )
{
if ( ( ( IWineD3DSurfaceImpl * ) resource ) - > hDC = = dc )
{
TRACE ( " Found surface %p for dc %p. \n " , resource , dc ) ;
* surface = ( IWineD3DSurface * ) resource ;
return WINED3D_OK ;
}
}
}
return WINED3DERR_INVALIDCALL ;
}
2004-10-07 06:22:21 +02:00
/**********************************************************
* IWineD3DDevice VTbl follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-11-18 10:45:53 +01:00
static const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
2004-10-07 06:22:21 +02:00
{
2005-03-02 13:16:10 +01:00
/*** IUnknown methods ***/
2004-10-07 06:22:21 +02:00
IWineD3DDeviceImpl_QueryInterface ,
IWineD3DDeviceImpl_AddRef ,
2004-10-14 02:32:04 +02:00
IWineD3DDeviceImpl_Release ,
2005-03-02 13:16:10 +01:00
/*** IWineD3DDevice methods ***/
2004-11-23 14:52:46 +01:00
IWineD3DDeviceImpl_GetParent ,
2005-03-02 13:16:10 +01:00
/*** Creation methods**/
2009-02-23 09:16:02 +01:00
IWineD3DDeviceImpl_CreateBuffer ,
2004-10-21 22:59:12 +02:00
IWineD3DDeviceImpl_CreateVertexBuffer ,
2004-11-24 19:13:41 +01:00
IWineD3DDeviceImpl_CreateIndexBuffer ,
2004-10-21 22:59:12 +02:00
IWineD3DDeviceImpl_CreateStateBlock ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_CreateSurface ,
2009-02-24 07:43:02 +01:00
IWineD3DDeviceImpl_CreateRendertargetView ,
2005-01-17 14:44:57 +01:00
IWineD3DDeviceImpl_CreateTexture ,
IWineD3DDeviceImpl_CreateVolumeTexture ,
IWineD3DDeviceImpl_CreateVolume ,
IWineD3DDeviceImpl_CreateCubeTexture ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_CreateQuery ,
2008-10-28 09:27:20 +01:00
IWineD3DDeviceImpl_CreateSwapChain ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_CreateVertexDeclaration ,
2007-04-22 11:52:11 +02:00
IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_CreateVertexShader ,
2010-01-03 21:18:23 +01:00
IWineD3DDeviceImpl_CreateGeometryShader ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_CreatePixelShader ,
2006-04-17 17:04:59 +02:00
IWineD3DDeviceImpl_CreatePalette ,
2005-03-02 13:16:10 +01:00
/*** Odd functions **/
2006-04-12 21:08:57 +02:00
IWineD3DDeviceImpl_Init3D ,
2008-08-05 21:23:00 +02:00
IWineD3DDeviceImpl_InitGDI ,
2006-04-12 21:08:57 +02:00
IWineD3DDeviceImpl_Uninit3D ,
2008-08-05 21:23:00 +02:00
IWineD3DDeviceImpl_UninitGDI ,
2007-03-04 17:03:03 +01:00
IWineD3DDeviceImpl_SetMultithreaded ,
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl_EvictManagedResources ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_GetAvailableTextureMem ,
IWineD3DDeviceImpl_GetBackBuffer ,
IWineD3DDeviceImpl_GetCreationParameters ,
IWineD3DDeviceImpl_GetDeviceCaps ,
IWineD3DDeviceImpl_GetDirect3D ,
IWineD3DDeviceImpl_GetDisplayMode ,
2006-04-17 17:51:21 +02:00
IWineD3DDeviceImpl_SetDisplayMode ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_GetNumberOfSwapChains ,
IWineD3DDeviceImpl_GetRasterStatus ,
IWineD3DDeviceImpl_GetSwapChain ,
IWineD3DDeviceImpl_Reset ,
IWineD3DDeviceImpl_SetDialogBoxMode ,
IWineD3DDeviceImpl_SetCursorProperties ,
IWineD3DDeviceImpl_SetCursorPosition ,
IWineD3DDeviceImpl_ShowCursor ,
/*** Getters and setters **/
IWineD3DDeviceImpl_SetClipPlane ,
IWineD3DDeviceImpl_GetClipPlane ,
IWineD3DDeviceImpl_SetClipStatus ,
IWineD3DDeviceImpl_GetClipStatus ,
IWineD3DDeviceImpl_SetCurrentTexturePalette ,
IWineD3DDeviceImpl_GetCurrentTexturePalette ,
IWineD3DDeviceImpl_SetDepthStencilSurface ,
IWineD3DDeviceImpl_GetDepthStencilSurface ,
IWineD3DDeviceImpl_SetGammaRamp ,
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl_GetGammaRamp ,
2009-09-25 13:31:45 +02:00
IWineD3DDeviceImpl_SetIndexBuffer ,
2009-09-25 13:31:46 +02:00
IWineD3DDeviceImpl_GetIndexBuffer ,
2007-06-04 18:12:36 +02:00
IWineD3DDeviceImpl_SetBaseVertexIndex ,
2007-06-06 18:40:02 +02:00
IWineD3DDeviceImpl_GetBaseVertexIndex ,
2004-11-29 18:53:42 +01:00
IWineD3DDeviceImpl_SetLight ,
IWineD3DDeviceImpl_GetLight ,
IWineD3DDeviceImpl_SetLightEnable ,
IWineD3DDeviceImpl_GetLightEnable ,
IWineD3DDeviceImpl_SetMaterial ,
IWineD3DDeviceImpl_GetMaterial ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_SetNPatchMode ,
2005-07-13 16:15:54 +02:00
IWineD3DDeviceImpl_GetNPatchMode ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_SetPaletteEntries ,
IWineD3DDeviceImpl_GetPaletteEntries ,
IWineD3DDeviceImpl_SetPixelShader ,
IWineD3DDeviceImpl_GetPixelShader ,
IWineD3DDeviceImpl_SetPixelShaderConstantB ,
IWineD3DDeviceImpl_GetPixelShaderConstantB ,
IWineD3DDeviceImpl_SetPixelShaderConstantI ,
IWineD3DDeviceImpl_GetPixelShaderConstantI ,
IWineD3DDeviceImpl_SetPixelShaderConstantF ,
IWineD3DDeviceImpl_GetPixelShaderConstantF ,
2004-12-13 14:35:38 +01:00
IWineD3DDeviceImpl_SetRenderState ,
IWineD3DDeviceImpl_GetRenderState ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_SetRenderTarget ,
IWineD3DDeviceImpl_GetRenderTarget ,
2006-04-15 22:40:14 +02:00
IWineD3DDeviceImpl_SetFrontBackBuffers ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_SetSamplerState ,
IWineD3DDeviceImpl_GetSamplerState ,
IWineD3DDeviceImpl_SetScissorRect ,
IWineD3DDeviceImpl_GetScissorRect ,
IWineD3DDeviceImpl_SetSoftwareVertexProcessing ,
IWineD3DDeviceImpl_GetSoftwareVertexProcessing ,
IWineD3DDeviceImpl_SetStreamSource ,
IWineD3DDeviceImpl_GetStreamSource ,
IWineD3DDeviceImpl_SetStreamSourceFreq ,
IWineD3DDeviceImpl_GetStreamSourceFreq ,
IWineD3DDeviceImpl_SetTexture ,
2005-06-24 13:53:07 +02:00
IWineD3DDeviceImpl_GetTexture ,
2004-12-13 14:35:38 +01:00
IWineD3DDeviceImpl_SetTextureStageState ,
IWineD3DDeviceImpl_GetTextureStageState ,
2005-03-02 13:16:10 +01:00
IWineD3DDeviceImpl_SetTransform ,
IWineD3DDeviceImpl_GetTransform ,
IWineD3DDeviceImpl_SetVertexDeclaration ,
IWineD3DDeviceImpl_GetVertexDeclaration ,
IWineD3DDeviceImpl_SetVertexShader ,
IWineD3DDeviceImpl_GetVertexShader ,
IWineD3DDeviceImpl_SetVertexShaderConstantB ,
IWineD3DDeviceImpl_GetVertexShaderConstantB ,
IWineD3DDeviceImpl_SetVertexShaderConstantI ,
IWineD3DDeviceImpl_GetVertexShaderConstantI ,
IWineD3DDeviceImpl_SetVertexShaderConstantF ,
IWineD3DDeviceImpl_GetVertexShaderConstantF ,
IWineD3DDeviceImpl_SetViewport ,
2008-03-04 02:30:23 +01:00
IWineD3DDeviceImpl_GetViewport ,
IWineD3DDeviceImpl_MultiplyTransform ,
IWineD3DDeviceImpl_ValidateDevice ,
IWineD3DDeviceImpl_ProcessVertices ,
/*** State block ***/
IWineD3DDeviceImpl_BeginStateBlock ,
IWineD3DDeviceImpl_EndStateBlock ,
/*** Scene management ***/
IWineD3DDeviceImpl_BeginScene ,
IWineD3DDeviceImpl_EndScene ,
IWineD3DDeviceImpl_Present ,
IWineD3DDeviceImpl_Clear ,
2009-02-25 08:39:01 +01:00
IWineD3DDeviceImpl_ClearRendertargetView ,
2008-03-04 02:30:23 +01:00
/*** Drawing ***/
2009-03-05 12:30:43 +01:00
IWineD3DDeviceImpl_SetPrimitiveType ,
IWineD3DDeviceImpl_GetPrimitiveType ,
2008-03-04 02:30:23 +01:00
IWineD3DDeviceImpl_DrawPrimitive ,
IWineD3DDeviceImpl_DrawIndexedPrimitive ,
IWineD3DDeviceImpl_DrawPrimitiveUP ,
IWineD3DDeviceImpl_DrawIndexedPrimitiveUP ,
IWineD3DDeviceImpl_DrawPrimitiveStrided ,
IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided ,
IWineD3DDeviceImpl_DrawRectPatch ,
IWineD3DDeviceImpl_DrawTriPatch ,
IWineD3DDeviceImpl_DeletePatch ,
IWineD3DDeviceImpl_ColorFill ,
IWineD3DDeviceImpl_UpdateTexture ,
IWineD3DDeviceImpl_UpdateSurface ,
IWineD3DDeviceImpl_GetFrontBufferData ,
/*** object tracking ***/
2010-03-16 19:02:21 +01:00
IWineD3DDeviceImpl_EnumResources ,
IWineD3DDeviceImpl_GetSurfaceFromDC ,
2010-03-17 21:59:49 +01:00
IWineD3DDeviceImpl_AcquireFocusWindow ,
IWineD3DDeviceImpl_ReleaseFocusWindow ,
2008-03-04 02:30:23 +01:00
} ;
2005-07-05 16:05:18 +02:00
2009-11-18 10:45:53 +01:00
HRESULT device_init ( IWineD3DDeviceImpl * device , IWineD3DImpl * wined3d ,
UINT adapter_idx , WINED3DDEVTYPE device_type , HWND focus_window , DWORD flags ,
IUnknown * parent , IWineD3DDeviceParent * device_parent )
{
struct wined3d_adapter * adapter = & wined3d - > adapters [ adapter_idx ] ;
const struct fragment_pipeline * fragment_pipeline ;
struct shader_caps shader_caps ;
struct fragment_caps ffp_caps ;
WINED3DDISPLAYMODE mode ;
unsigned int i ;
HRESULT hr ;
device - > lpVtbl = & IWineD3DDevice_Vtbl ;
device - > ref = 1 ;
2009-12-07 20:20:02 +01:00
device - > wined3d = ( IWineD3D * ) wined3d ;
IWineD3D_AddRef ( device - > wined3d ) ;
2009-11-18 10:45:53 +01:00
device - > adapter = wined3d - > adapter_count ? adapter : NULL ;
device - > parent = parent ;
device - > device_parent = device_parent ;
list_init ( & device - > resources ) ;
list_init ( & device - > shaders ) ;
device - > surface_alignment = wined3d - > dxVersion = = 7 ? DDRAW_PITCH_ALIGNMENT : D3D8_PITCH_ALIGNMENT ;
device - > posFixup [ 0 ] = 1.0f ; /* This is needed to get the x coord unmodified through a MAD. */
/* Get the initial screen setup for ddraw. */
hr = IWineD3D_GetAdapterDisplayMode ( ( IWineD3D * ) wined3d , adapter_idx , & mode ) ;
if ( FAILED ( hr ) )
{
ERR ( " Failed to get the adapter's display mode, hr %#x. \n " , hr ) ;
2009-12-07 20:20:02 +01:00
IWineD3D_Release ( device - > wined3d ) ;
2009-11-18 10:45:53 +01:00
return hr ;
}
device - > ddraw_width = mode . Width ;
device - > ddraw_height = mode . Height ;
device - > ddraw_format = mode . Format ;
/* Save the creation parameters. */
device - > createParms . AdapterOrdinal = adapter_idx ;
device - > createParms . DeviceType = device_type ;
device - > createParms . hFocusWindow = focus_window ;
device - > createParms . BehaviorFlags = flags ;
device - > devType = device_type ;
for ( i = 0 ; i < PATCHMAP_SIZE ; + + i ) list_init ( & device - > patches [ i ] ) ;
select_shader_mode ( & adapter - > gl_info , & device - > ps_selected_mode , & device - > vs_selected_mode ) ;
2010-02-02 12:06:57 +01:00
device - > shader_backend = adapter - > shader_backend ;
2009-11-18 10:45:53 +01:00
memset ( & shader_caps , 0 , sizeof ( shader_caps ) ) ;
2010-02-03 18:18:00 +01:00
device - > shader_backend - > shader_get_caps ( & adapter - > gl_info , & shader_caps ) ;
2009-11-18 10:45:53 +01:00
device - > d3d_vshader_constantF = shader_caps . MaxVertexShaderConst ;
device - > d3d_pshader_constantF = shader_caps . MaxPixelShaderConst ;
device - > vs_clipping = shader_caps . VSClipping ;
memset ( & ffp_caps , 0 , sizeof ( ffp_caps ) ) ;
2010-02-02 12:06:56 +01:00
fragment_pipeline = adapter - > fragment_pipe ;
2009-11-18 10:45:53 +01:00
device - > frag_pipe = fragment_pipeline ;
2010-02-03 18:17:59 +01:00
fragment_pipeline - > get_caps ( & adapter - > gl_info , & ffp_caps ) ;
2009-11-18 10:45:53 +01:00
device - > max_ffp_textures = ffp_caps . MaxSimultaneousTextures ;
hr = compile_state_table ( device - > StateTable , device - > multistate_funcs , & adapter - > gl_info ,
ffp_vertexstate_template , fragment_pipeline , misc_state_template ) ;
if ( FAILED ( hr ) )
{
ERR ( " Failed to compile state table, hr %#x. \n " , hr ) ;
2009-12-07 20:20:02 +01:00
IWineD3D_Release ( device - > wined3d ) ;
2009-11-18 10:45:53 +01:00
return hr ;
}
2010-02-03 11:02:20 +01:00
device - > blitter = adapter - > blitter ;
2009-11-18 10:45:53 +01:00
return WINED3D_OK ;
}
2006-12-19 13:00:03 +01:00
void IWineD3DDeviceImpl_MarkStateDirty ( IWineD3DDeviceImpl * This , DWORD state ) {
2008-07-02 01:23:44 +02:00
DWORD rep = This - > StateTable [ state ] . representative ;
2009-08-03 08:06:51 +02:00
struct wined3d_context * context ;
2006-12-19 13:00:03 +01:00
DWORD idx ;
BYTE shift ;
2007-02-12 19:18:31 +01:00
UINT i ;
2006-12-19 13:00:03 +01:00
2007-02-12 19:18:31 +01:00
for ( i = 0 ; i < This - > numContexts ; i + + ) {
2007-02-12 19:35:45 +01:00
context = This - > contexts [ i ] ;
2007-02-12 19:18:31 +01:00
if ( isStateDirty ( context , rep ) ) continue ;
context - > dirtyArray [ context - > numDirtyEntries + + ] = rep ;
2009-12-29 17:10:22 +01:00
idx = rep / ( sizeof ( * context - > isStateDirty ) * CHAR_BIT ) ;
shift = rep & ( ( sizeof ( * context - > isStateDirty ) * CHAR_BIT ) - 1 ) ;
2007-02-12 19:18:31 +01:00
context - > isStateDirty [ idx ] | = ( 1 < < shift ) ;
}
2006-12-19 13:00:03 +01:00
}
2007-11-30 20:22:33 +01:00
2009-08-03 08:06:51 +02:00
void get_drawable_size_fbo ( struct wined3d_context * context , UINT * width , UINT * height )
2009-07-24 10:44:15 +02:00
{
/* The drawable size of a fbo target is the opengl texture size, which is the power of two size. */
2010-04-21 22:02:31 +02:00
* width = context - > current_rt - > pow2Width ;
* height = context - > current_rt - > pow2Height ;
2007-11-30 20:22:33 +01:00
}
2009-08-03 08:06:51 +02:00
void get_drawable_size_backbuffer ( struct wined3d_context * context , UINT * width , UINT * height )
2009-07-24 10:44:15 +02:00
{
2010-03-15 21:07:25 +01:00
IWineD3DSwapChainImpl * swapchain = context - > swapchain ;
2007-11-30 20:22:33 +01:00
/* The drawable size of a backbuffer / aux buffer offscreen target is the size of the
* current context ' s drawable , which is the size of the back buffer of the swapchain
2010-03-15 21:07:25 +01:00
* the active context belongs to . */
* width = swapchain - > presentParms . BackBufferWidth ;
* height = swapchain - > presentParms . BackBufferHeight ;
2007-11-30 20:22:33 +01:00
}
2009-12-22 18:32:13 +01:00
LRESULT device_process_message ( IWineD3DDeviceImpl * device , HWND window ,
UINT message , WPARAM wparam , LPARAM lparam , WNDPROC proc )
{
if ( device - > filter_messages )
{
TRACE ( " Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx. \n " ,
window , message , wparam , lparam ) ;
return DefWindowProcW ( window , message , wparam , lparam ) ;
}
if ( message = = WM_DESTROY )
{
TRACE ( " unregister window %p. \n " , window ) ;
wined3d_unregister_window ( window ) ;
2009-12-28 17:38:04 +01:00
if ( device - > focus_window = = window ) device - > focus_window = NULL ;
else ERR ( " Window %p is not the focus window for device %p. \n " , window , device ) ;
2009-12-22 18:32:13 +01:00
}
return CallWindowProcW ( proc , window , message , wparam , lparam ) ;
}