wined3d_private.h 90.7 KB
Newer Older
1 2 3 4 5
/*
 * Direct3D wine internal private include file
 *
 * Copyright 2002-2003 The wine-d3d team
 * Copyright 2002-2003 Raphael Junqueira
Oliver Stieber's avatar
Oliver Stieber committed
6 7
 * Copyright 2004 Jason Edmeades
 * Copyright 2005 Oliver Stieber
8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * 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
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 23 24 25 26 27
 */

#ifndef __WINE_WINED3D_PRIVATE_H
#define __WINE_WINED3D_PRIVATE_H

#include <stdarg.h>
28
#include <math.h>
29 30
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
31
#define COBJMACROS
32 33
#include "windef.h"
#include "winbase.h"
34
#include "winreg.h"
35 36 37
#include "wingdi.h"
#include "winuser.h"
#include "wine/debug.h"
38
#include "wine/unicode.h"
39

40
#include "wined3d_private_types.h"
41
#include "wine/wined3d_interface.h"
42
#include "wine/wined3d_caps.h"
43
#include "wine/wined3d_gl.h"
44
#include "wine/list.h"
45

46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
/* Hash table functions */
typedef unsigned int (hash_function_t)(void *key);
typedef BOOL (compare_function_t)(void *keya, void *keyb);

typedef struct {
    void *key;
    void *value;
    unsigned int hash;
    struct list entry;
} hash_table_entry_t;

typedef struct {
    hash_function_t *hash_function;
    compare_function_t *compare_function;
    struct list *buckets;
    unsigned int bucket_count;
    hash_table_entry_t *entries;
    unsigned int entry_count;
    struct list free_entries;
    unsigned int count;
    unsigned int grow_size;
    unsigned int shrink_size;
} hash_table_t;

hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function);
void hash_table_destroy(hash_table_t *table);
void *hash_table_get(hash_table_t *table, void *key);
void hash_table_put(hash_table_t *table, void *key, void *value);
void hash_table_remove(hash_table_t *table, void *key);

76
/* Device caps */
77 78 79 80 81 82 83 84 85
#define MAX_PALETTES            256
#define MAX_STREAMS             16
#define MAX_TEXTURES            8
#define MAX_FRAGMENT_SAMPLERS   16
#define MAX_VERTEX_SAMPLERS     4
#define MAX_COMBINED_SAMPLERS   (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS)
#define MAX_ACTIVE_LIGHTS       8
#define MAX_CLIPPLANES          WINED3DMAXUSERCLIPPLANES
#define MAX_LEVELS              256
86

87 88
#define MAX_CONST_I 16
#define MAX_CONST_B 16
89

90 91 92 93
/* Used for CreateStateBlock */
#define NUM_SAVEDPIXELSTATES_R     35
#define NUM_SAVEDPIXELSTATES_T     18
#define NUM_SAVEDPIXELSTATES_S     12
94
#define NUM_SAVEDVERTEXSTATES_R    34
95 96 97 98 99 100 101 102 103 104
#define NUM_SAVEDVERTEXSTATES_T    2
#define NUM_SAVEDVERTEXSTATES_S    1

extern const DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R];
extern const DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T];
extern const DWORD SavedPixelStates_S[NUM_SAVEDPIXELSTATES_S];
extern const DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R];
extern const DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T];
extern const DWORD SavedVertexStates_S[NUM_SAVEDVERTEXSTATES_S];

105 106 107 108 109 110 111 112 113 114
typedef enum _WINELOOKUP {
    WINELOOKUP_WARPPARAM = 0,
    WINELOOKUP_MAGFILTER = 1,
    MAX_LOOKUPS          = 2
} WINELOOKUP;

extern int minLookup[MAX_LOOKUPS];
extern int maxLookup[MAX_LOOKUPS];
extern DWORD *stateLookup[MAX_LOOKUPS];

115
extern DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1];
116

117 118 119 120 121 122
void init_type_lookup(WineD3D_GL_Info *gl_info);
#define WINED3D_ATR_TYPE(type)          GLINFO_LOCATION.glTypeLookup[type].d3dType
#define WINED3D_ATR_SIZE(type)          GLINFO_LOCATION.glTypeLookup[type].size
#define WINED3D_ATR_GLTYPE(type)        GLINFO_LOCATION.glTypeLookup[type].glType
#define WINED3D_ATR_NORMALIZED(type)    GLINFO_LOCATION.glTypeLookup[type].normalized
#define WINED3D_ATR_TYPESIZE(type)      GLINFO_LOCATION.glTypeLookup[type].typesize
123

124 125 126 127 128 129 130 131 132
/* The following functions convert 16 bit floats in the FLOAT16 data type
 * to standard C floats and vice versa. They do not depend on the encoding
 * of the C float, so they are platform independent, but slow. On x86 and
 * other IEEE 754 compliant platforms the conversion can be accelerated with
 * bitshifting the exponent and mantissa. There are also some SSE-based
 * assembly routines out there
 *
 * See GL_NV_half_float for a reference of the FLOAT16 / GL_HALF format
 */
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
static inline float float_16_to_32(const unsigned short *in) {
    const unsigned short s = ((*in) & 0x8000);
    const unsigned short e = ((*in) & 0x7C00) >> 10;
    const unsigned short m = (*in) & 0x3FF;
    const float sgn = (s ? -1.0 : 1.0);

    if(e == 0) {
        if(m == 0) return sgn * 0.0; /* +0.0 or -0.0 */
        else return sgn * pow(2, -14.0) * ( (float) m / 1024.0);
    } else if(e < 31) {
        return sgn * pow(2, (float) e-15.0) * (1.0 + ((float) m / 1024.0));
    } else {
        if(m == 0) return sgn / 0.0; /* +INF / -INF */
        else return 0.0 / 0.0; /* NAN */
    }
}

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
static inline unsigned short float_32_to_16(const float *in) {
    int exp = 0;
    float tmp = fabs(*in);
    unsigned int mantissa;
    unsigned short ret;

    /* Deal with special numbers */
    if(*in == 0.0) return 0x0000;
    if(isnan(*in)) return 0x7C01;
    if(isinf(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00);

    if(tmp < pow(2, 10)) {
        do
        {
            tmp = tmp * 2.0;
            exp--;
        }while(tmp < pow(2, 10));
    } else if(tmp >= pow(2, 11)) {
        do
        {
            tmp /= 2.0;
            exp++;
        }while(tmp >= pow(2, 11));
    }

    mantissa = (unsigned int) tmp;
    if(tmp - mantissa >= 0.5) mantissa++; /* round to nearest, away from zero */

    exp += 10;  /* Normalize the mantissa */
    exp += 15;  /* Exponent is encoded with excess 15 */

    if(exp > 30) { /* too big */
        ret = 0x7c00; /* INF */
    } else if(exp <= 0) {
        /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers */
        while(exp <= 0) {
            mantissa = mantissa >> 1;
            exp++;
        }
        ret = mantissa & 0x3ff;
    } else {
        ret = (exp << 10) | (mantissa & 0x3ff);
    }

    ret |= ((*in < 0.0 ? 1 : 0) << 15); /* Add the sign */
    return ret;
}

198 199 200
/**
 * Settings 
 */
201 202
#define VS_NONE    0
#define VS_HW      1
203

204 205
#define PS_NONE    0
#define PS_HW      1
206

207 208 209 210 211
#define VBO_NONE   0
#define VBO_HW     1

#define NP2_NONE   0
#define NP2_REPACK 1
212
#define NP2_NATIVE 2
213

214 215
#define ORM_BACKBUFFER  0
#define ORM_PBUFFER     1
216
#define ORM_FBO         2
217

218 219
#define SHADER_ARB  1
#define SHADER_GLSL 2
220
#define SHADER_NONE 3
221

222 223 224 225 226 227 228
#define RTL_DISABLE   -1
#define RTL_AUTO       0
#define RTL_READDRAW   1
#define RTL_READTEX    2
#define RTL_TEXDRAW    3
#define RTL_TEXTEX     4

229 230
/* NOTE: When adding fields to this structure, make sure to update the default
 * values in wined3d_main.c as well. */
231 232 233 234 235
typedef struct wined3d_settings_s {
/* vertex and pixel shader modes */
  int vs_mode;
  int ps_mode;
  int vbo_mode;
236 237 238
/* Ideally, we don't want the user to have to request GLSL.  If the hardware supports GLSL,
    we should use it.  However, until it's fully implemented, we'll leave it as a registry
    setting for developers. */
239
  BOOL glslRequested;
240
  int offscreen_rendering_mode;
241
  int rendertargetlock_mode;
242 243
/* Memory tracking and object counting */
  unsigned int emulated_textureram;
244
  char *logo;
245 246 247 248
} wined3d_settings_t;

extern wined3d_settings_t wined3d_settings;

249
/* Shader backends */
250
struct SHADER_OPCODE_ARG;
251 252 253 254

typedef struct {
    void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
    void (*shader_select_depth_blt)(IWineD3DDevice *iface);
255
    void (*shader_destroy_depth_blt)(IWineD3DDevice *iface);
256
    void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
257
    void (*shader_cleanup)(IWineD3DDevice *iface);
258
    void (*shader_color_correction)(struct SHADER_OPCODE_ARG *arg);
259
    void (*shader_destroy)(IWineD3DBaseShader *iface);
260 261
    HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
    void (*shader_free_private)(IWineD3DDevice *iface);
262
    BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
263 264 265 266 267 268
} shader_backend_t;

extern const shader_backend_t glsl_shader_backend;
extern const shader_backend_t arb_program_shader_backend;
extern const shader_backend_t none_shader_backend;

269 270 271 272 273 274 275 276 277 278 279
/* GLSL shader private data */
struct shader_glsl_priv {
    GLhandleARB             depth_blt_glsl_program_id;
};

/* ARB_program_shader private data */
struct shader_arb_priv {
    GLuint                  depth_blt_vprogram_id;
    GLuint                  depth_blt_fprogram_id;
};

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
/* X11 locking */

extern void (*wine_tsx11_lock_ptr)(void);
extern void (*wine_tsx11_unlock_ptr)(void);

/* As GLX relies on X, this is needed */
extern int num_lock;

#if 0
#define ENTER_GL() ++num_lock; if (num_lock > 1) FIXME("Recursive use of GL lock to: %d\n", num_lock); wine_tsx11_lock_ptr()
#define LEAVE_GL() if (num_lock != 1) FIXME("Recursive use of GL lock: %d\n", num_lock); --num_lock; wine_tsx11_unlock_ptr()
#else
#define ENTER_GL() wine_tsx11_lock_ptr()
#define LEAVE_GL() wine_tsx11_unlock_ptr()
#endif

/*****************************************************************************
 * Defines
 */
299 300 301

/* GL related defines */
/* ------------------ */
302 303
#define GL_SUPPORT(ExtName)           (GLINFO_LOCATION.supported[ExtName] != 0)
#define GL_LIMITS(ExtName)            (GLINFO_LOCATION.max_##ExtName)
304
#define GL_EXTCALL(FuncName)          (GLINFO_LOCATION.FuncName)
305
#define GL_VEND(_VendName)            (GLINFO_LOCATION.gl_vendor == VENDOR_##_VendName ? TRUE : FALSE)
306

307 308 309 310 311
#define D3DCOLOR_B_R(dw) (((dw) >> 16) & 0xFF)
#define D3DCOLOR_B_G(dw) (((dw) >>  8) & 0xFF)
#define D3DCOLOR_B_B(dw) (((dw) >>  0) & 0xFF)
#define D3DCOLOR_B_A(dw) (((dw) >> 24) & 0xFF)

312 313 314 315 316 317 318 319 320 321
#define D3DCOLOR_R(dw) (((float) (((dw) >> 16) & 0xFF)) / 255.0f)
#define D3DCOLOR_G(dw) (((float) (((dw) >>  8) & 0xFF)) / 255.0f)
#define D3DCOLOR_B(dw) (((float) (((dw) >>  0) & 0xFF)) / 255.0f)
#define D3DCOLOR_A(dw) (((float) (((dw) >> 24) & 0xFF)) / 255.0f)

#define D3DCOLORTOGLFLOAT4(dw, vec) \
  (vec)[0] = D3DCOLOR_R(dw); \
  (vec)[1] = D3DCOLOR_G(dw); \
  (vec)[2] = D3DCOLOR_B(dw); \
  (vec)[3] = D3DCOLOR_A(dw);
322

323 324
/* DirectX Device Limits */
/* --------------------- */
325 326
#define MAX_LEVELS  256  /* Maximum number of mipmap levels. Guessed at 256 */

327 328
#define MAX_STREAMS  16  /* Maximum possible streams - used for fixed size arrays
                            See MaxStreams in MSDN under GetDeviceCaps */
329
                         /* Maximum number of constants provided to the shaders */
330
#define HIGHEST_TRANSFORMSTATE 512 
331
                         /* Highest value in WINED3DTRANSFORMSTATETYPE */
332 333
#define MAX_PALETTES      256

334 335
/* Checking of API calls */
/* --------------------- */
336 337 338 339 340 341 342
#define checkGLcall(A)                                          \
{                                                               \
    GLint err = glGetError();                                   \
    if (err == GL_NO_ERROR) {                                   \
       TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__);    \
                                                                \
    } else do {                                                 \
343 344
        FIXME(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \
            debug_glerror(err), err, A, __FILE__, __LINE__);    \
345 346 347
       err = glGetError();                                      \
    } while (err != GL_NO_ERROR);                               \
} 
348

349 350 351 352
/* Trace routines / diagnostics */
/* ---------------------------- */

/* Dump out a matrix and copy it */
353 354 355 356 357 358 359 360 361
#define conv_mat(mat,gl_mat)                                                                \
do {                                                                                        \
    TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
    TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
    TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
    TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
    memcpy(gl_mat, (mat), 16 * sizeof(float));                                              \
} while (0)

362 363 364 365 366 367 368 369 370 371
/* Macro to dump out the current state of the light chain */
#define DUMP_LIGHT_CHAIN()                    \
{                                             \
  PLIGHTINFOEL *el = This->stateBlock->lights;\
  while (el) {                                \
    TRACE("Light %p (glIndex %ld, d3dIndex %ld, enabled %d)\n", el, el->glIndex, el->OriginalIndex, el->lightEnabled);\
    el = el->next;                            \
  }                                           \
}

372
/* Trace vector and strided data information */
373
#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
374 375
#define TRACE_STRIDED(sd,name) TRACE( #name "=(data:%p, stride:%d, type:%d, vbo %d, stream %u)\n", \
        sd->u.s.name.lpData, sd->u.s.name.dwStride, sd->u.s.name.dwType, sd->u.s.name.VBO, sd->u.s.name.streamNo);
376

377 378 379 380 381 382 383
/* Defines used for optimizations */

/*    Only reapply what is necessary */
#define REAPPLY_ALPHAOP  0x0001
#define REAPPLY_ALL      0xFFFF

/* Advance declaration of structures to satisfy compiler */
384
typedef struct IWineD3DStateBlockImpl IWineD3DStateBlockImpl;
385
typedef struct IWineD3DSurfaceImpl    IWineD3DSurfaceImpl;
386
typedef struct IWineD3DPaletteImpl    IWineD3DPaletteImpl;
387
typedef struct IWineD3DDeviceImpl     IWineD3DDeviceImpl;
388

389
/* Global variables */
390 391
extern const float identity[16];

392 393 394 395 396 397 398 399 400 401 402 403
/*****************************************************************************
 * Compilable extra diagnostics
 */

/* Trace information per-vertex: (extremely high amount of trace) */
#if 0 /* NOTE: Must be 0 in cvs */
# define VTRACE(A) TRACE A
#else 
# define VTRACE(A) 
#endif

/* Checking of per-vertex related GL calls */
404 405 406 407 408
/* --------------------- */
#define vcheckGLcall(A)                                         \
{                                                               \
    GLint err = glGetError();                                   \
    if (err == GL_NO_ERROR) {                                   \
409
       VTRACE(("%s call ok %s / %d\n", A, __FILE__, __LINE__)); \
410 411
                                                                \
    } else do {                                                 \
412 413
        FIXME(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \
            debug_glerror(err), err, A, __FILE__, __LINE__);    \
414 415
       err = glGetError();                                      \
    } while (err != GL_NO_ERROR);                               \
416 417
}

418 419 420
/* TODO: Confirm each of these works when wined3d move completed */
#if 0 /* NOTE: Must be 0 in cvs */
  /* To avoid having to get gigabytes of trace, the following can be compiled in, and at the start
421 422
     of each frame, a check is made for the existence of C:\D3DTRACE, and if it exists d3d trace
     is enabled, and if it doesn't exist it is disabled. */
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
# define FRAME_DEBUGGING
  /*  Adding in the SINGLE_FRAME_DEBUGGING gives a trace of just what makes up a single frame, before
      the file is deleted                                                                            */
# if 1 /* NOTE: Must be 1 in cvs, as this is mostly more useful than a trace from program start */
#  define SINGLE_FRAME_DEBUGGING
# endif  
  /* The following, when enabled, lets you see the makeup of the frame, by drawprimitive calls.
     It can only be enabled when FRAME_DEBUGGING is also enabled                               
     The contents of the back buffer are written into /tmp/backbuffer_* after each primitive 
     array is drawn.                                                                            */
# if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */                                                                                       
#  define SHOW_FRAME_MAKEUP 1
# endif  
  /* The following, when enabled, lets you see the makeup of the all the textures used during each
     of the drawprimitive calls. It can only be enabled when SHOW_FRAME_MAKEUP is also enabled.
     The contents of the textures assigned to each stage are written into 
     /tmp/texture_*_<Stage>.ppm after each primitive array is drawn.                            */
# if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */
#  define SHOW_TEXTURE_MAKEUP 0
# endif  
extern BOOL isOn;
extern BOOL isDumpingFrames;
extern LONG primCounter;
#endif

448 449 450 451 452 453 454 455 456 457
/*****************************************************************************
 * Prototypes
 */

/* Routine common to the draw primitive and draw indexed primitive routines */
void drawPrimitive(IWineD3DDevice *iface,
                    int PrimitiveType,
                    long NumPrimitives,
                    /* for Indexed: */
                    long  StartVertexIndex,
458
                    UINT  numberOfVertices,
459 460 461
                    long  StartIdx,
                    short idxBytes,
                    const void *idxData,
462
                    int   minIndex);
463

464 465 466 467 468 469
void primitiveDeclarationConvertToStridedData(
     IWineD3DDevice *iface,
     BOOL useVertexShaderFunction,
     WineDirect3DVertexStridedData *strided,
     BOOL *fixup);

470 471
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);

472 473 474 475 476 477 478
typedef void (*glAttribFunc)(void *data);
typedef void (*glTexAttribFunc)(GLuint unit, void *data);
extern glAttribFunc position_funcs[WINED3DDECLTYPE_UNUSED];
extern glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED];
extern glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
extern glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];

479 480
#define eps 1e-8

481 482 483
#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
    (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)

484 485
void depth_copy(IWineD3DDevice *iface);

486
/* Routines and structures related to state management */
487
typedef struct WineD3DContext WineD3DContext;
488
typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *ctx);
489

490 491 492
#define STATE_RENDER(a) (a)
#define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE))

493 494 495
#define STATE_TEXTURESTAGE(stage, num) (STATE_RENDER(WINEHIGHEST_RENDER_STATE) + (stage) * WINED3D_HIGHEST_TEXTURE_STATE + (num))
#define STATE_IS_TEXTURESTAGE(a) ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE))

496 497
/* + 1 because samplers start with 0 */
#define STATE_SAMPLER(num) (STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE) + 1 + (num))
498
#define STATE_IS_SAMPLER(num) ((num) >= STATE_SAMPLER(0) && (num) <= STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1))
499

500
#define STATE_PIXELSHADER (STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1) + 1)
501 502
#define STATE_IS_PIXELSHADER(a) ((a) == STATE_PIXELSHADER)

503 504 505
#define STATE_TRANSFORM(a) (STATE_PIXELSHADER + (a))
#define STATE_IS_TRANSFORM(a) ((a) >= STATE_TRANSFORM(1) && (a) <= STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)))

506 507
#define STATE_STREAMSRC (STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)) + 1)
#define STATE_IS_STREAMSRC(a) ((a) == STATE_STREAMSRC)
508 509
#define STATE_INDEXBUFFER (STATE_STREAMSRC + 1)
#define STATE_IS_INDEXBUFFER(a) ((a) == STATE_INDEXBUFFER)
510

511
#define STATE_VDECL (STATE_INDEXBUFFER + 1)
512 513 514 515 516
#define STATE_IS_VDECL(a) ((a) == STATE_VDECL)

#define STATE_VSHADER (STATE_VDECL + 1)
#define STATE_IS_VSHADER(a) ((a) == STATE_VSHADER)

517 518 519
#define STATE_VIEWPORT (STATE_VSHADER + 1)
#define STATE_IS_VIEWPORT(a) ((a) == STATE_VIEWPORT)

520 521 522 523 524
#define STATE_VERTEXSHADERCONSTANT (STATE_VIEWPORT + 1)
#define STATE_PIXELSHADERCONSTANT (STATE_VERTEXSHADERCONSTANT + 1)
#define STATE_IS_VERTEXSHADERCONSTANT(a) ((a) == STATE_VERTEXSHADERCONSTANT)
#define STATE_IS_PIXELSHADERCONSTANT(a) ((a) == STATE_PIXELSHADERCONSTANT)

525
#define STATE_ACTIVELIGHT(a) (STATE_PIXELSHADERCONSTANT + (a) + 1)
526
#define STATE_IS_ACTIVELIGHT(a) ((a) >= STATE_ACTIVELIGHT(0) && (a) < STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS))
527

528 529 530
#define STATE_SCISSORRECT (STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS - 1) + 1)
#define STATE_IS_SCISSORRECT(a) ((a) == STATE_SCISSORRECT)

531 532 533
#define STATE_CLIPPLANE(a) (STATE_SCISSORRECT + 1 + (a))
#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIPPLANES - 1))

534 535
#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIPPLANES))

536 537 538
#define STATE_FRONTFACE (STATE_MATERIAL + 1)

#define STATE_HIGHEST (STATE_FRONTFACE)
539

540 541 542 543 544 545 546 547 548
struct StateEntry
{
    DWORD           representative;
    APPLYSTATEFUNC  apply;
};

/* Global state table */
extern const struct StateEntry StateTable[];

549 550 551 552 553 554 555 556 557 558 559 560
/* The new context manager that should deal with onscreen and offscreen rendering */
struct WineD3DContext {
    /* State dirtification
     * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
     * 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed,
     * but with the help of both it is easy to find out if a state is dirty(just check the array index), and for applying dirty states
     * only numDirtyEntries array elements have to be checked, not STATE_HIGHEST states.
     */
    DWORD                   dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */
    DWORD                   numDirtyEntries;
    DWORD                   isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */

561
    IWineD3DSurface         *surface;
562
    DWORD                   tid;    /* Thread ID which owns this context at the moment */
563

564
    /* Stores some information about the context state for optimization */
565
    GLint                   last_draw_buffer;
566 567 568 569 570 571 572
    BOOL                    last_was_rhw;      /* true iff last draw_primitive was in xyzrhw mode */
    BOOL                    last_was_pshader;
    BOOL                    last_was_vshader;
    BOOL                    last_was_foggy_shader;
    BOOL                    namedArraysLoaded, numberedArraysLoaded;
    BOOL                    lastWasPow2Texture[MAX_TEXTURES];
    GLenum                  tracking_parm;     /* Which source is tracking current colour         */
573 574
    unsigned char           num_untracked_materials;
    GLenum                  untracked_materials[2];
575
    BOOL                    last_was_blit, last_was_ckey;
576
    char                    texShaderBumpMap;
577
    BOOL                    fog_coord;
578

579 580
    char                    *vshader_const_dirty, *pshader_const_dirty;

581
    /* The actual opengl context */
582 583 584 585
    HGLRC                   glCtx;
    HWND                    win_handle;
    HDC                     hdc;
    HPBUFFERARB             pbuffer;
586
    BOOL                    isPBuffer;
587 588
};

589 590
typedef enum ContextUsage {
    CTXUSAGE_RESOURCELOAD       = 1,    /* Only loads textures: No State is applied */
591
    CTXUSAGE_DRAWPRIM           = 2,    /* OpenGL states are set up for blitting DirectDraw surfaces */
592
    CTXUSAGE_BLIT               = 3,    /* OpenGL states are set up 3D drawing */
593
    CTXUSAGE_CLEAR              = 4,    /* Drawable and states are set up for clearing */
594 595 596
} ContextUsage;

void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
597
WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
598
void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
599
void apply_fbo_state(IWineD3DDevice *iface);
600

601 602 603 604 605 606
/* Macros for doing basic GPU detection based on opengl capabilities */
#define WINE_D3D6_CAPABLE(gl_info) (gl_info->supported[ARB_MULTITEXTURE])
#define WINE_D3D7_CAPABLE(gl_info) (gl_info->supported[ARB_TEXTURE_COMPRESSION] && gl_info->supported[ARB_TEXTURE_CUBE_MAP] && gl_info->supported[ARB_TEXTURE_ENV_DOT3])
#define WINE_D3D8_CAPABLE(gl_info) WINE_D3D7_CAPABLE(gl_info) && (gl_info->supported[ARB_MULTISAMPLE] && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
#define WINE_D3D9_CAPABLE(gl_info) WINE_D3D8_CAPABLE(gl_info) && (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[ARB_VERTEX_SHADER])

607 608 609
/* Default callbacks for implicit object destruction */
extern ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface);

610 611
extern ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pSurface);

612 613 614 615 616 617 618 619 620 621
/*****************************************************************************
 * Internal representation of a light
 */
typedef struct PLIGHTINFOEL PLIGHTINFOEL;
struct PLIGHTINFOEL {
    WINED3DLIGHT OriginalParms; /* Note D3D8LIGHT == D3D9LIGHT */
    DWORD        OriginalIndex;
    LONG         glIndex;
    BOOL         changed;
    BOOL         enabledChanged;
622
    BOOL         enabled;
623 624 625 626 627 628 629

    /* Converted parms to speed up swapping lights */
    float                         lightPosn[4];
    float                         lightDirn[4];
    float                         exponent;
    float                         cutoff;

630
    struct list entry;
631 632
};

633 634 635
/* The default light parameters */
extern const WINED3DLIGHT WINED3D_default_light;

636 637 638 639 640 641 642
typedef struct WineD3D_PixelFormat
{
    int iPixelFormat; /* WGL pixel format */
    int redSize, greenSize, blueSize, alphaSize;
    int depthSize, stencilSize;
} WineD3D_PixelFormat;

643
/* The adapter structure */
644
typedef struct GLPixelFormatDesc GLPixelFormatDesc;
645 646
struct WineD3DAdapter
{
647
    UINT                    num;
648 649
    POINT                   monitorPoint;
    WineD3D_GL_Info         gl_info;
650 651
    const char              *driver;
    const char              *description;
652
    WCHAR                   DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
653
    int                     nCfgs;
654
    WineD3D_PixelFormat     *cfgs;
655 656
    unsigned int            TextureRam; /* Amount of texture memory both video ram + AGP/TurboCache/HyperMemory/.. */
    unsigned int            UsedTextureRam;
657 658 659
};

extern BOOL InitAdapters(void);
660
extern BOOL initPixelFormats(WineD3D_GL_Info *gl_info);
661
extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram);
662

663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
/*****************************************************************************
 * High order patch management
 */
struct WineD3DRectPatch
{
    UINT                            Handle;
    float                          *mem;
    WineDirect3DVertexStridedData   strided;
    WINED3DRECTPATCH_INFO           RectPatchInfo;
    float                           numSegs[4];
    char                            has_normals, has_texcoords;
    struct list                     entry;
};

HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, struct WineD3DRectPatch *patch);

679 680 681 682 683 684
/*****************************************************************************
 * IWineD3D implementation structure
 */
typedef struct IWineD3DImpl
{
    /* IUnknown fields */
685
    const IWineD3DVtbl     *lpVtbl;
686
    LONG                    ref;     /* Note: Ref counting not required */
687 688

    /* WineD3D Information */
689
    IUnknown               *parent;
690 691 692
    UINT                    dxVersion;
} IWineD3DImpl;

693
extern const IWineD3DVtbl IWineD3D_Vtbl;
694

695
/* TODO: setup some flags in the registry to enable, disable pbuffer support
696 697 698 699 700
(since it will break quite a few things until contexts are managed properly!) */
extern BOOL pbuffer_support;
/* allocate one pbuffer per surface */
extern BOOL pbuffer_per_surface;

701
/* A helper function that dumps a resource list */
702
void dumpResources(struct list *list);
703

704 705 706
/*****************************************************************************
 * IWineD3DDevice implementation structure
 */
707
struct IWineD3DDeviceImpl
708
{
709
    /* IUnknown fields      */
710
    const IWineD3DDeviceVtbl *lpVtbl;
711
    LONG                    ref;     /* Note: Ref counting not required */
712

713
    /* WineD3D Information  */
714
    IUnknown               *parent;
715
    IWineD3D               *wineD3D;
716
    struct WineD3DAdapter  *adapter;
717

718 719 720 721
    /* Window styles to restore when switching fullscreen mode */
    LONG                    style;
    LONG                    exStyle;

722 723
    /* X and GL Information */
    GLint                   maxConcurrentLights;
724
    GLenum                  offscreenBuffer;
725

726 727 728
    /* Selected capabilities */
    int vs_selected_mode;
    int ps_selected_mode;
729
    const shader_backend_t *shader_backend;
730
    hash_table_t *glsl_program_lookup;
731
    void *shader_priv;
732

733
    /* To store */
734
    BOOL                    view_ident;        /* true iff view matrix is identity                */
735
    BOOL                    untransformed;
736
    BOOL                    vertexBlendUsed;   /* To avoid needless setting of the blend matrices */
737
    unsigned char           surface_alignment; /* Line Alignment of surfaces                      */
738

739 740 741 742
    /* State block related */
    BOOL                    isRecordingState;
    IWineD3DStateBlockImpl *stateBlock;
    IWineD3DStateBlockImpl *updateStateBlock;
743
    BOOL                   isInDraw;
744

745
    /* Internal use fields  */
746
    WINED3DDEVICE_CREATION_PARAMETERS createParms;
747
    UINT                            adapterNo;
748
    WINED3DDEVTYPE                  devType;
749

750
    IWineD3DSwapChain     **swapchains;
751
    UINT                    NumberOfSwapChains;
Oliver Stieber's avatar
Oliver Stieber committed
752

753
    struct list             resources; /* a linked list to track resources created by the device */
754
    struct list             shaders;   /* a linked list to track shaders (pixel and vertex)      */
755
    unsigned int            highest_dirty_ps_const, highest_dirty_vs_const;
756

757
    /* Render Target Support */
758
    IWineD3DSurface       **render_targets;
759
    IWineD3DSurface        *auto_depth_stencil_buffer;
760 761
    IWineD3DSurface       **fbo_color_attachments;
    IWineD3DSurface        *fbo_depth_attachment;
762

763
    IWineD3DSurface        *stencilBufferTarget;
764

765 766 767 768
    /* Caches to avoid unneeded context changes */
    IWineD3DSurface        *lastActiveRenderTarget;
    IWineD3DSwapChain      *lastActiveSwapChain;

769
    /* palettes texture management */
770 771
    PALETTEENTRY            palettes[MAX_PALETTES][256];
    UINT                    currentPalette;
772
    UINT                    paletteConversionShader;
773

774
    /* For rendering to a texture using glCopyTexImage */
775
    BOOL                    render_offscreen;
776
    WINED3D_DEPTHCOPYSTATE  depth_copy_state;
777
    GLuint                  fbo;
778 779
    GLuint                  src_fbo;
    GLuint                  dst_fbo;
780
    GLenum                  *draw_buffers;
781
    GLuint                  depth_blt_texture;
782

783 784 785 786 787 788
    /* Cursor management */
    BOOL                    bCursorVisible;
    UINT                    xHotSpot;
    UINT                    yHotSpot;
    UINT                    xScreenSpace;
    UINT                    yScreenSpace;
789 790
    UINT                    cursorWidth, cursorHeight;
    GLuint                  cursorTexture;
791 792
    BOOL                    haveHardwareCursor;
    HCURSOR                 hardwareCursor;
793

794 795 796
    /* The Wine logo surface */
    IWineD3DSurface        *logo_surface;

797
    /* Textures for when no other textures are mapped */
798
    UINT                          dummyTextureName[MAX_TEXTURES];
799

800 801 802
    /* Debug stream management */
    BOOL                     debug;

803 804
    /* Device state management */
    HRESULT                 state;
805
    BOOL                    d3d_initialized;
806

807 808
    /* A flag to check for proper BeginScene / EndScene call pairs */
    BOOL inScene;
809 810 811

    /* process vertex shaders using software or hardware */
    BOOL softwareVertexProcessing;
812 813 814

    /* DirectDraw stuff */
    HWND ddraw_window;
815
    IWineD3DSurface *ddraw_primary;
816 817
    DWORD ddraw_width, ddraw_height;
    WINED3DFORMAT ddraw_format;
818
    BOOL ddraw_fullscreen;
819

820 821
    /* Final position fixup constant */
    float                       posFixup[4];
822

823
    /* With register combiners we can skip junk texture stages */
824 825
    DWORD                     texUnitMap[MAX_COMBINED_SAMPLERS];
    DWORD                     rev_tex_unit_map[MAX_COMBINED_SAMPLERS];
826
    BOOL                      fixed_function_usage_map[MAX_TEXTURES];
827

828 829
    /* Stream source management */
    WineDirect3DVertexStridedData strided_streams;
830
    WineDirect3DVertexStridedData *up_strided;
831
    BOOL                      useDrawStridedSlow;
832
    BOOL                      instancedDraw;
833

834
    /* Context management */
835
    WineD3DContext          **contexts;                  /* Dynamic array containing pointers to context structures */
836 837 838
    WineD3DContext          *activeContext;
    DWORD                   lastThread;
    UINT                    numContexts;
839 840
    WineD3DContext          *pbufferContext;             /* The context that has a pbuffer as drawable */
    DWORD                   pbufferWidth, pbufferHeight; /* Size of the buffer drawable */
841 842 843 844 845 846

    /* High level patch management */
#define PATCHMAP_SIZE 43
#define PATCHMAP_HASHFUNC(x) ((x) % PATCHMAP_SIZE) /* Primitive and simple function */
    struct list             patches[PATCHMAP_SIZE];
    struct WineD3DRectPatch *currentPatch;
847
};
848

849
extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl, IWineD3DDevice_DirtyConst_Vtbl;
850

851 852 853
HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfaceImpl *target, DWORD Count,
                                        CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color,
                                        float Z, DWORD Stencil);
854
void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This);
855
void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state);
856
static inline BOOL isStateDirty(WineD3DContext *context, DWORD state) {
857 858
    DWORD idx = state >> 5;
    BYTE shift = state & 0x1f;
859
    return context->isStateDirty[idx] & (1 << shift);
860 861
}

862
/* Support for IWineD3DResource ::Set/Get/FreePrivateData. */
863 864
typedef struct PrivateData
{
865
    struct list entry;
866 867 868 869 870 871 872 873 874 875 876 877 878 879

    GUID tag;
    DWORD flags; /* DDSPD_* */
    DWORD uniqueness_value;

    union
    {
        LPVOID data;
        LPUNKNOWN object;
    } ptr;

    DWORD size;
} PrivateData;

880 881 882 883 884 885
/*****************************************************************************
 * IWineD3DResource implementation structure
 */
typedef struct IWineD3DResourceClass
{
    /* IUnknown fields */
886
    LONG                    ref;     /* Note: Ref counting not required */
887 888

    /* WineD3DResource Information */
889
    IUnknown               *parent;
890
    WINED3DRESOURCETYPE     resourceType;
891
    IWineD3DDeviceImpl     *wineD3DDevice;
892
    WINED3DPOOL             pool;
893 894 895
    UINT                    size;
    DWORD                   usage;
    WINED3DFORMAT           format;
896 897
    BYTE                   *allocatedMemory; /* Pointer to the real data location */
    BYTE                   *heapMemory; /* Pointer to the HeapAlloced block of memory */
898
    struct list             privateData;
899
    struct list             resource_list_entry;
900 901 902 903 904 905

} IWineD3DResourceClass;

typedef struct IWineD3DResourceImpl
{
    /* IUnknown & WineD3DResource Information     */
906
    const IWineD3DResourceVtbl *lpVtbl;
907 908 909
    IWineD3DResourceClass   resource;
} IWineD3DResourceImpl;

910 911
/* Tests show that the start address of resources is 32 byte aligned */
#define RESOURCE_ALIGNMENT 32
912 913 914 915

/*****************************************************************************
 * IWineD3DVertexBuffer implementation structure (extends IWineD3DResourceImpl)
 */
916 917 918 919 920 921 922 923 924 925 926
enum vbo_conversion_type {
    CONV_NONE               = 0,
    CONV_D3DCOLOR           = 1,
    CONV_POSITIONT          = 2,
    CONV_FLOAT16_2          = 3 /* Also handles FLOAT16_4 */

    /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other
     * fixed function semantics as D3DCOLOR or FLOAT16
     */
};

927 928 929
typedef struct IWineD3DVertexBufferImpl
{
    /* IUnknown & WineD3DResource Information     */
930
    const IWineD3DVertexBufferVtbl *lpVtbl;
931 932 933
    IWineD3DResourceClass     resource;

    /* WineD3DVertexBuffer specifics */
934
    DWORD                     fvf;
935

936 937 938
    /* Vertex buffer object support */
    GLuint                    vbo;
    BYTE                      Flags;
939
    LONG                      bindCount;
940 941
    LONG                      vbo_size;
    GLenum                    vbo_usage;
942 943

    UINT                      dirtystart, dirtyend;
944
    LONG                      lockcount;
945

946
    LONG                      declChanges, draws;
947
    /* Last description of the buffer */
948 949
    DWORD                     stride;       /* 0 if no conversion               */
    enum vbo_conversion_type  *conv_map;    /* NULL if no conversion            */
950 951

    /* Extra load offsets, for FLOAT16 conversion */
952 953
    DWORD                     *conv_shift;  /* NULL if no shifted conversion    */
    DWORD                     conv_stride;  /* 0 if no shifted conversion       */
954 955
} IWineD3DVertexBufferImpl;

956
extern const IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl;
957

958 959 960 961
#define VBFLAG_OPTIMIZED      0x01    /* Optimize has been called for the VB */
#define VBFLAG_DIRTY          0x02    /* Buffer data has been modified */
#define VBFLAG_HASDESC        0x04    /* A vertex description has been found */
#define VBFLAG_CREATEVBO      0x08    /* Attempt to create a VBO next PreLoad */
962

963 964 965 966 967 968
/*****************************************************************************
 * IWineD3DIndexBuffer implementation structure (extends IWineD3DResourceImpl)
 */
typedef struct IWineD3DIndexBufferImpl
{
    /* IUnknown & WineD3DResource Information     */
969
    const IWineD3DIndexBufferVtbl *lpVtbl;
970 971
    IWineD3DResourceClass     resource;

972 973 974 975
    GLuint                    vbo;
    UINT                      dirtystart, dirtyend;
    LONG                      lockcount;

976 977 978
    /* WineD3DVertexBuffer specifics */
} IWineD3DIndexBufferImpl;

979
extern const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl;
980

981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
/*****************************************************************************
 * IWineD3DBaseTexture D3D- > openGL state map lookups
 */
#define WINED3DFUNC_NOTSUPPORTED  -2
#define WINED3DFUNC_UNIMPLEMENTED -1

typedef enum winetexturestates {
    WINED3DTEXSTA_ADDRESSU       = 0,
    WINED3DTEXSTA_ADDRESSV       = 1,
    WINED3DTEXSTA_ADDRESSW       = 2,
    WINED3DTEXSTA_BORDERCOLOR    = 3,
    WINED3DTEXSTA_MAGFILTER      = 4,
    WINED3DTEXSTA_MINFILTER      = 5,
    WINED3DTEXSTA_MIPFILTER      = 6,
    WINED3DTEXSTA_MAXMIPLEVEL    = 7,
    WINED3DTEXSTA_MAXANISOTROPY  = 8,
    WINED3DTEXSTA_SRGBTEXTURE    = 9,
    WINED3DTEXSTA_ELEMENTINDEX   = 10,
    WINED3DTEXSTA_DMAPOFFSET     = 11,
    WINED3DTEXSTA_TSSADDRESSW    = 12,
    MAX_WINETEXTURESTATES        = 13,
} winetexturestates;

1004 1005 1006 1007 1008 1009
/*****************************************************************************
 * IWineD3DBaseTexture implementation structure (extends IWineD3DResourceImpl)
 */
typedef struct IWineD3DBaseTextureClass
{
    UINT                    levels;
1010
    BOOL                    dirty;
1011
    UINT                    textureName;
1012
    UINT                    LOD;
1013
    WINED3DTEXTUREFILTERTYPE filterType;
1014
    DWORD                   states[MAX_WINETEXTURESTATES];
1015 1016
    LONG                    bindCount;
    DWORD                   sampler;
1017 1018
    BOOL                    is_srgb;
    UINT                    srgb_mode_change_count;
1019
    WINED3DFORMAT           shader_conversion_group;
1020
    float                   pow2Matrix[16];
1021 1022 1023 1024 1025
} IWineD3DBaseTextureClass;

typedef struct IWineD3DBaseTextureImpl
{
    /* IUnknown & WineD3DResource Information     */
1026
    const IWineD3DBaseTextureVtbl *lpVtbl;
1027 1028 1029 1030 1031
    IWineD3DResourceClass     resource;
    IWineD3DBaseTextureClass  baseTexture;

} IWineD3DBaseTextureImpl;

1032 1033 1034 1035 1036 1037
/*****************************************************************************
 * IWineD3DTexture implementation structure (extends IWineD3DBaseTextureImpl)
 */
typedef struct IWineD3DTextureImpl
{
    /* IUnknown & WineD3DResource/WineD3DBaseTexture Information     */
1038
    const IWineD3DTextureVtbl *lpVtbl;
1039 1040 1041 1042
    IWineD3DResourceClass     resource;
    IWineD3DBaseTextureClass  baseTexture;

    /* IWineD3DTexture */
1043
    IWineD3DSurface          *surfaces[MAX_LEVELS];
1044 1045 1046
    
    UINT                      width;
    UINT                      height;
1047
    UINT                      target;
1048 1049 1050

} IWineD3DTextureImpl;

1051
extern const IWineD3DTextureVtbl IWineD3DTexture_Vtbl;
1052 1053 1054 1055 1056 1057 1058

/*****************************************************************************
 * IWineD3DCubeTexture implementation structure (extends IWineD3DBaseTextureImpl)
 */
typedef struct IWineD3DCubeTextureImpl
{
    /* IUnknown & WineD3DResource/WineD3DBaseTexture Information     */
1059
    const IWineD3DCubeTextureVtbl *lpVtbl;
1060 1061 1062 1063
    IWineD3DResourceClass     resource;
    IWineD3DBaseTextureClass  baseTexture;

    /* IWineD3DCubeTexture */
1064
    IWineD3DSurface          *surfaces[6][MAX_LEVELS];
1065 1066 1067 1068

    UINT                      edgeLength;
} IWineD3DCubeTextureImpl;

1069
extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl;
1070

1071 1072 1073 1074 1075 1076 1077
typedef struct _WINED3DVOLUMET_DESC
{
    UINT                    Width;
    UINT                    Height;
    UINT                    Depth;
} WINED3DVOLUMET_DESC;

1078 1079 1080 1081 1082
/*****************************************************************************
 * IWineD3DVolume implementation structure (extends IUnknown)
 */
typedef struct IWineD3DVolumeImpl
{
1083
    /* IUnknown & WineD3DResource fields */
1084
    const IWineD3DVolumeVtbl  *lpVtbl;
1085
    IWineD3DResourceClass      resource;
1086 1087

    /* WineD3DVolume Information */
1088
    WINED3DVOLUMET_DESC      currentDesc;
H. Verbeet's avatar
H. Verbeet committed
1089
    IWineD3DBase            *container;
1090 1091 1092 1093
    UINT                    bytesPerPixel;

    BOOL                    lockable;
    BOOL                    locked;
1094 1095
    WINED3DBOX              lockedBox;
    WINED3DBOX              dirtyBox;
1096 1097 1098 1099 1100
    BOOL                    dirty;


} IWineD3DVolumeImpl;

1101
extern const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl;
1102 1103 1104 1105 1106 1107 1108

/*****************************************************************************
 * IWineD3DVolumeTexture implementation structure (extends IWineD3DBaseTextureImpl)
 */
typedef struct IWineD3DVolumeTextureImpl
{
    /* IUnknown & WineD3DResource/WineD3DBaseTexture Information     */
1109
    const IWineD3DVolumeTextureVtbl *lpVtbl;
1110 1111 1112 1113
    IWineD3DResourceClass     resource;
    IWineD3DBaseTextureClass  baseTexture;

    /* IWineD3DVolumeTexture */
1114
    IWineD3DVolume           *volumes[MAX_LEVELS];
1115 1116 1117 1118 1119 1120

    UINT                      width;
    UINT                      height;
    UINT                      depth;
} IWineD3DVolumeTextureImpl;

1121
extern const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl;
1122

1123 1124
typedef struct _WINED3DSURFACET_DESC
{
1125 1126 1127 1128
    WINED3DMULTISAMPLE_TYPE MultiSampleType;
    DWORD                   MultiSampleQuality;
    UINT                    Width;
    UINT                    Height;
1129 1130
} WINED3DSURFACET_DESC;

1131 1132 1133 1134 1135 1136
/*****************************************************************************
 * Structure for DIB Surfaces (GetDC and GDI surfaces)
 */
typedef struct wineD3DSurface_DIB {
    HBITMAP DIBsection;
    void* bitmap_data;
1137
    UINT bitmap_size;
1138 1139 1140 1141
    HGDIOBJ holdbitmap;
    BOOL client_memory;
} wineD3DSurface_DIB;

1142 1143 1144 1145 1146 1147 1148
typedef struct {
    struct list entry;
    GLuint id;
    UINT width;
    UINT height;
} renderbuffer_entry_t;

1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
/*****************************************************************************
 * IWineD3DClipp implementation structure
 */
typedef struct IWineD3DClipperImpl
{
    const IWineD3DClipperVtbl *lpVtbl;
    LONG ref;

    IUnknown *Parent;
    HWND hWnd;
} IWineD3DClipperImpl;


1162 1163 1164 1165 1166 1167
/*****************************************************************************
 * IWineD3DSurface implementation structure
 */
struct IWineD3DSurfaceImpl
{
    /* IUnknown & IWineD3DResource Information     */
1168
    const IWineD3DSurfaceVtbl *lpVtbl;
1169 1170 1171
    IWineD3DResourceClass     resource;

    /* IWineD3DSurface fields */
H. Verbeet's avatar
H. Verbeet committed
1172
    IWineD3DBase              *container;
1173
    WINED3DSURFACET_DESC      currentDesc;
1174 1175
    IWineD3DPaletteImpl       *palette; /* D3D7 style palette handling */
    PALETTEENTRY              *palette9; /* D3D8/9 style palette handling */
1176 1177

    UINT                      bytesPerPixel;
1178 1179

    /* TODO: move this off into a management class(maybe!) */
1180
    DWORD                      Flags;
1181 1182 1183 1184

    UINT                      pow2Width;
    UINT                      pow2Height;

1185 1186 1187
    /* A method to retrieve the drawable size. Not in the Vtable to make it changeable */
    void (*get_drawable_size)(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);

1188 1189 1190
    /* Oversized texture */
    RECT                      glRect;

1191 1192 1193
    /* PBO */
    GLuint                    pbo;

1194 1195
    RECT                      lockedRect;
    RECT                      dirtyRect;
1196 1197
    int                       lockCount;
#define MAXLOCKCOUNT          50 /* After this amount of locks do not free the sysmem copy */
1198 1199

    glDescriptor              glDescription;
1200
    BOOL                      srgb;
1201 1202 1203 1204

    /* For GetDC */
    wineD3DSurface_DIB        dib;
    HDC                       hDC;
1205 1206

    /* Color keys for DDraw */
1207 1208 1209 1210
    WINEDDCOLORKEY            DestBltCKey;
    WINEDDCOLORKEY            DestOverlayCKey;
    WINEDDCOLORKEY            SrcOverlayCKey;
    WINEDDCOLORKEY            SrcBltCKey;
1211 1212
    DWORD                     CKeyFlags;

1213
    WINEDDCOLORKEY            glCKey;
1214 1215 1216

    struct list               renderbuffers;
    renderbuffer_entry_t      *current_renderbuffer;
1217 1218 1219

    /* DirectDraw clippers */
    IWineD3DClipper           *clipper;
1220 1221
};

1222
extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
1223 1224 1225
extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl;

/* Predeclare the shared Surface functions */
1226
HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj);
1227 1228 1229 1230 1231 1232 1233 1234 1235
ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **pParent);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPrivateData(IWineD3DSurface *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, REFGUID refguid);
DWORD   WINAPI IWineD3DBaseSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD PriorityNew);
DWORD   WINAPI IWineD3DBaseSurfaceImpl_GetPriority(IWineD3DSurface *iface);
WINED3DRESOURCETYPE WINAPI IWineD3DBaseSurfaceImpl_GetType(IWineD3DSurface *iface);
1236 1237 1238 1239 1240 1241
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetFlipStatus(IWineD3DSurface *iface, DWORD Flags);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_IsLost(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Restore(IWineD3DSurface *iface);
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD3DPalette **Pal);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD Flags, WINEDDCOLORKEY *CKey);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container);
DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetOverlayPosition(IWineD3DSurface *iface, LONG X, LONG Y);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetOverlayPosition(IWineD3DSurface *iface, LONG *X, LONG *Y);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_UpdateOverlayZOrder(IWineD3DSurface *iface, DWORD Flags, IWineD3DSurface *Ref);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_UpdateOverlay(IWineD3DSurface *iface, RECT *SrcRect, IWineD3DSurface *DstSurface, RECT *DstRect, DWORD Flags, WINEDDOVERLAYFX *FX);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetClipper(IWineD3DSurface *iface, IWineD3DClipper *clipper);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DClipper **clipper);
1254
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format);
1255
HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface);
1256 1257
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans);
1258
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags);
1259
void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface);
1260

1261 1262
const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface);

1263 1264 1265 1266 1267
void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);

1268
/* Surface flags: */
1269 1270 1271
#define SFLAG_OVERSIZE    0x00000001 /* Surface is bigger than gl size, blts only */
#define SFLAG_CONVERTED   0x00000002 /* Converted for color keying or Palettized */
#define SFLAG_DIBSECTION  0x00000004 /* Has a DIB section attached for getdc */
1272 1273 1274 1275 1276 1277
#define SFLAG_LOCKABLE    0x00000008 /* Surface can be locked */
#define SFLAG_DISCARD     0x00000010 /* ??? */
#define SFLAG_LOCKED      0x00000020 /* Surface is locked atm */
#define SFLAG_INTEXTURE   0x00000040 /* The GL texture contains the newest surface content */
#define SFLAG_INDRAWABLE  0x00000080 /* The gl drawable contains the most up to date data */
#define SFLAG_INSYSMEM    0x00000100 /* The system memory copy is most up to date */
1278 1279 1280 1281
#define SFLAG_NONPOW2     0x00000200 /* Surface sizes are not a power of 2 */
#define SFLAG_DYNLOCK     0x00000400 /* Surface is often locked by the app */
#define SFLAG_DYNCHANGE   0x00000C00 /* Surface contents are changed very often, implies DYNLOCK */
#define SFLAG_DCINUSE     0x00001000 /* Set between GetDC and ReleaseDC calls */
1282
#define SFLAG_LOST        0x00002000 /* Surface lost flag for DDraw */
1283 1284
#define SFLAG_USERPTR     0x00004000 /* The application allocated the memory for this surface */
#define SFLAG_GLCKEY      0x00008000 /* The gl texture was created with a color key */
1285
#define SFLAG_CLIENT      0x00010000 /* GL_APPLE_client_storage is used on that texture */
1286
#define SFLAG_ALLOCATED   0x00020000 /* A gl texture is allocated for this surface */
1287
#define SFLAG_PBO         0x00040000 /* Has a PBO attached for speeding up data transfers for dynamically locked surfaces */
1288 1289 1290 1291 1292 1293 1294 1295

/* In some conditions the surface memory must not be freed:
 * SFLAG_OVERSIZE: Not all data can be kept in GL
 * SFLAG_CONVERTED: Converting the data back would take too long
 * SFLAG_DIBSECTION: The dib code manages the memory
 * SFLAG_LOCKED: The app requires access to the surface data
 * SFLAG_DYNLOCK: Avoid freeing the data for performance
 * SFLAG_DYNCHANGE: Same reason as DYNLOCK
1296
 * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
1297
 * SFLAG_CLIENT: OpenGL uses our memory as backup
1298 1299 1300 1301 1302 1303
 */
#define SFLAG_DONOTFREE  (SFLAG_OVERSIZE   | \
                          SFLAG_CONVERTED  | \
                          SFLAG_DIBSECTION | \
                          SFLAG_LOCKED     | \
                          SFLAG_DYNLOCK    | \
1304
                          SFLAG_DYNCHANGE  | \
1305
                          SFLAG_USERPTR    | \
1306
                          SFLAG_PBO        | \
1307
                          SFLAG_CLIENT)
1308

1309 1310 1311
#define SFLAG_LOCATIONS  (SFLAG_INSYSMEM   | \
                          SFLAG_INTEXTURE  | \
                          SFLAG_INDRAWABLE)
1312 1313
BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]);

1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
typedef enum {
    NO_CONVERSION,
    CONVERT_PALETTED,
    CONVERT_PALETTED_CK,
    CONVERT_CK_565,
    CONVERT_CK_5551,
    CONVERT_CK_4444,
    CONVERT_CK_4444_ARGB,
    CONVERT_CK_1555,
    CONVERT_555,
    CONVERT_CK_RGB24,
    CONVERT_CK_8888,
    CONVERT_CK_8888_ARGB,
    CONVERT_RGB32_888,
    CONVERT_V8U8,
1329
    CONVERT_L6V5U5,
1330 1331 1332
    CONVERT_X8L8V8U8,
    CONVERT_Q8W8V8U8,
    CONVERT_V16U16,
1333 1334
    CONVERT_A4L4,
    CONVERT_R32F,
1335 1336
    CONVERT_R16F,
    CONVERT_G16R16,
1337 1338 1339 1340
} CONVERT_TYPES;

HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);

1341 1342 1343
/*****************************************************************************
 * IWineD3DVertexDeclaration implementation structure
 */
1344 1345 1346 1347 1348 1349 1350
typedef struct attrib_declaration {
    DWORD usage;
    DWORD idx;
} attrib_declaration;

#define MAX_ATTRIBS 16

1351
typedef struct IWineD3DVertexDeclarationImpl {
1352 1353 1354 1355 1356 1357 1358 1359 1360
    /* IUnknown  Information */
    const IWineD3DVertexDeclarationVtbl *lpVtbl;
    LONG                    ref;

    IUnknown                *parent;
    IWineD3DDeviceImpl      *wineD3DDevice;

    WINED3DVERTEXELEMENT    *pDeclarationWine;
    UINT                    declarationWNumElements;
1361 1362 1363

    DWORD                   streams[MAX_STREAMS];
    UINT                    num_streams;
1364
    BOOL                    position_transformed;
1365
    BOOL                    half_float_conv_needed;
1366 1367 1368 1369

    /* Ordered array of declaration types that need swizzling in a vshader */
    attrib_declaration      swizzled_attribs[MAX_ATTRIBS];
    UINT                    num_swizzled_attribs;
1370 1371
} IWineD3DVertexDeclarationImpl;

1372
extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl;
1373

1374 1375 1376 1377 1378 1379 1380 1381
/*****************************************************************************
 * IWineD3DStateBlock implementation structure
 */

/* Internal state Block for Begin/End/Capture/Create/Apply info  */
/*   Note: Very long winded but gl Lists are not flexible enough */
/*   to resolve everything we need, so doing it manually for now */
typedef struct SAVEDSTATES {
1382
        BOOL                      indices;
1383
        BOOL                      material;
1384
        BOOL                      fvf;
1385 1386
        BOOL                      streamSource[MAX_STREAMS];
        BOOL                      streamFreq[MAX_STREAMS];
1387
        BOOL                      textures[MAX_COMBINED_SAMPLERS];
1388
        BOOL                      transform[HIGHEST_TRANSFORMSTATE + 1];
1389
        BOOL                      viewport;
1390
        BOOL                      renderState[WINEHIGHEST_RENDER_STATE + 1];
1391
        BOOL                      textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
1392
        BOOL                      samplerState[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
1393
        BOOL                      clipplane[MAX_CLIPPLANES];
1394
        BOOL                      vertexDecl;
1395
        BOOL                      pixelShader;
1396 1397 1398
        BOOL                      pixelShaderConstantsB[MAX_CONST_B];
        BOOL                      pixelShaderConstantsI[MAX_CONST_I];
        BOOL                     *pixelShaderConstantsF;
1399
        BOOL                      vertexShader;
1400 1401 1402
        BOOL                      vertexShaderConstantsB[MAX_CONST_B];
        BOOL                      vertexShaderConstantsI[MAX_CONST_I];
        BOOL                     *vertexShaderConstantsF;
1403
        BOOL                      scissorRect;
1404 1405
} SAVEDSTATES;

1406
typedef struct {
1407 1408 1409 1410
    struct  list entry;
    DWORD   count;
    DWORD   idx[13];
} constants_entry;
1411

1412 1413 1414 1415 1416
struct StageState {
    DWORD stage;
    DWORD state;
};

1417 1418 1419
struct IWineD3DStateBlockImpl
{
    /* IUnknown fields */
1420
    const IWineD3DStateBlockVtbl *lpVtbl;
1421
    LONG                      ref;     /* Note: Ref counting not required */
1422

1423
    /* IWineD3DStateBlock information */
1424
    IUnknown                 *parent;
1425
    IWineD3DDeviceImpl       *wineD3DDevice;
1426
    WINED3DSTATEBLOCKTYPE     blockType;
1427 1428 1429

    /* Array indicating whether things have been set or changed */
    SAVEDSTATES               changed;
1430 1431
    struct list               set_vconstantsF;
    struct list               set_pconstantsF;
1432

1433 1434
    /* Drawing - Vertex Shader or FVF related */
    DWORD                     fvf;
1435
    /* Vertex Shader Declaration */
1436
    IWineD3DVertexDeclaration *vertexDecl;
1437

1438
    IWineD3DVertexShader      *vertexShader;
1439

1440
    /* Vertex Shader Constants */
1441 1442 1443
    BOOL                       vertexShaderConstantB[MAX_CONST_B];
    INT                        vertexShaderConstantI[MAX_CONST_I * 4];
    float                     *vertexShaderConstantF;
1444

1445
    /* Stream Source */
1446
    BOOL                      streamIsUP;
1447
    UINT                      streamStride[MAX_STREAMS];
1448
    UINT                      streamOffset[MAX_STREAMS + 1 /* tesselated pseudo-stream */ ];
1449
    IWineD3DVertexBuffer     *streamSource[MAX_STREAMS];
1450 1451
    UINT                      streamFreq[MAX_STREAMS + 1];
    UINT                      streamFlags[MAX_STREAMS + 1];     /*0 | WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA  */
1452

1453 1454
    /* Indices */
    IWineD3DIndexBuffer*      pIndexData;
1455 1456
    INT                       baseVertexIndex;
    INT                       loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */
1457

1458
    /* Transform */
1459
    WINED3DMATRIX             transforms[HIGHEST_TRANSFORMSTATE + 1];
1460

1461 1462 1463 1464 1465
    /* Light hashmap . Collisions are handled using standard wine double linked lists */
#define LIGHTMAP_SIZE 43 /* Use of a prime number recommended. Set to 1 for a linked list! */
#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE) /* Primitive and simple function */
    struct list               lightMap[LIGHTMAP_SIZE]; /* Mashmap containing the lights */
    PLIGHTINFOEL             *activeLights[MAX_ACTIVE_LIGHTS]; /* Map of opengl lights to d3d lights */
1466

1467 1468 1469 1470
    /* Clipping */
    double                    clipplane[MAX_CLIPPLANES][4];
    WINED3DCLIPSTATUS         clip_status;

1471 1472 1473
    /* ViewPort */
    WINED3DVIEWPORT           viewport;

1474 1475 1476
    /* Material */
    WINED3DMATERIAL           material;

1477
    /* Pixel Shader */
1478
    IWineD3DPixelShader      *pixelShader;
1479 1480

    /* Pixel Shader Constants */
1481 1482 1483
    BOOL                       pixelShaderConstantB[MAX_CONST_B];
    INT                        pixelShaderConstantI[MAX_CONST_I * 4];
    float                     *pixelShaderConstantF;
1484

1485
    /* RenderState */
1486
    DWORD                     renderState[WINEHIGHEST_RENDER_STATE + 1];
1487

1488
    /* Texture */
1489 1490
    IWineD3DBaseTexture      *textures[MAX_COMBINED_SAMPLERS];
    int                       textureDimensions[MAX_COMBINED_SAMPLERS];
1491 1492

    /* Texture State Stage */
1493
    DWORD                     textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
1494
    DWORD                     lowest_disabled_stage;
1495
    /* Sampler States */
1496
    DWORD                     samplerState[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
1497

1498
    /* Current GLSL Shader Program */
1499
    struct glsl_shader_prog_link *glsl_program;
1500 1501 1502

    /* Scissor test rectangle */
    RECT                      scissorRect;
1503 1504 1505 1506

    /* Contained state management */
    DWORD                     contained_render_states[WINEHIGHEST_RENDER_STATE + 1];
    unsigned int              num_contained_render_states;
1507
    DWORD                     contained_transform_states[HIGHEST_TRANSFORMSTATE + 1];
1508
    unsigned int              num_contained_transform_states;
1509 1510 1511 1512
    DWORD                     contained_vs_consts_i[MAX_CONST_I];
    unsigned int              num_contained_vs_consts_i;
    DWORD                     contained_vs_consts_b[MAX_CONST_B];
    unsigned int              num_contained_vs_consts_b;
1513 1514
    DWORD                     *contained_vs_consts_f;
    unsigned int              num_contained_vs_consts_f;
1515 1516 1517 1518
    DWORD                     contained_ps_consts_i[MAX_CONST_I];
    unsigned int              num_contained_ps_consts_i;
    DWORD                     contained_ps_consts_b[MAX_CONST_B];
    unsigned int              num_contained_ps_consts_b;
1519 1520
    DWORD                     *contained_ps_consts_f;
    unsigned int              num_contained_ps_consts_f;
1521 1522
    struct StageState         contained_tss_states[MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE)];
    unsigned int              num_contained_tss_states;
1523 1524
    struct StageState         contained_sampler_states[MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE];
    unsigned int              num_contained_sampler_states;
1525 1526
};

1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540
extern void stateblock_savedstates_set(
    IWineD3DStateBlock* iface,
    SAVEDSTATES* states,
    BOOL value);

extern void stateblock_savedstates_copy(
    IWineD3DStateBlock* iface,
    SAVEDSTATES* dest,
    SAVEDSTATES* source);

extern void stateblock_copy(
    IWineD3DStateBlock* destination,
    IWineD3DStateBlock* source);

1541
extern const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl;
1542

1543 1544 1545 1546 1547 1548 1549 1550 1551
/* Direct3D terminology with little modifications. We do not have an issued state
 * because only the driver knows about it, but we have a created state because d3d
 * allows GetData on a created issue, but opengl doesn't
 */
enum query_state {
    QUERY_CREATED,
    QUERY_SIGNALLED,
    QUERY_BUILDING
};
1552 1553 1554 1555 1556
/*****************************************************************************
 * IWineD3DQueryImpl implementation structure (extends IUnknown)
 */
typedef struct IWineD3DQueryImpl
{
1557
    const IWineD3DQueryVtbl  *lpVtbl;
1558
    LONG                      ref;     /* Note: Ref counting not required */
1559 1560 1561 1562 1563 1564 1565 1566 1567
    
    IUnknown                 *parent;
    /*TODO: replace with iface usage */
#if 0
    IWineD3DDevice         *wineD3DDevice;
#else
    IWineD3DDeviceImpl       *wineD3DDevice;
#endif

1568
    /* IWineD3DQuery fields */
1569
    enum query_state         state;
1570
    WINED3DQUERYTYPE         type;
1571
    /* TODO: Think about using a IUnknown instead of a void* */
1572 1573 1574 1575 1576
    void                     *extendedData;
    
  
} IWineD3DQueryImpl;

1577
extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
1578
extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl;
1579
extern const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl;
1580

1581 1582
/* Datastructures for IWineD3DQueryImpl.extendedData */
typedef struct  WineQueryOcclusionData {
1583
    GLuint  queryId;
1584
    WineD3DContext *ctx;
1585 1586
} WineQueryOcclusionData;

1587 1588
typedef struct  WineQueryEventData {
    GLuint  fenceId;
1589
    WineD3DContext *ctx;
1590
} WineQueryEventData;
1591

Oliver Stieber's avatar
Oliver Stieber committed
1592 1593 1594 1595 1596 1597 1598
/*****************************************************************************
 * IWineD3DSwapChainImpl implementation structure (extends IUnknown)
 */

typedef struct IWineD3DSwapChainImpl
{
    /*IUnknown part*/
1599
    const IWineD3DSwapChainVtbl *lpVtbl;
1600
    LONG                      ref;     /* Note: Ref counting not required */
Oliver Stieber's avatar
Oliver Stieber committed
1601 1602 1603 1604 1605

    IUnknown                 *parent;
    IWineD3DDeviceImpl       *wineD3DDevice;

    /* IWineD3DSwapChain fields */
1606
    IWineD3DSurface         **backBuffer;
Oliver Stieber's avatar
Oliver Stieber committed
1607 1608
    IWineD3DSurface          *frontBuffer;
    BOOL                      wantsDepthStencilBuffer;
1609
    WINED3DPRESENT_PARAMETERS presentParms;
1610
    DWORD                     orig_width, orig_height;
1611
    WINED3DFORMAT             orig_fmt;
Oliver Stieber's avatar
Oliver Stieber committed
1612

1613
    long prev_time, frames;   /* Performance tracking */
1614
    unsigned int vSyncCounter;
1615

1616 1617
    WineD3DContext        **context; /* Later a array for multithreading */
    unsigned int            num_contexts;
Oliver Stieber's avatar
Oliver Stieber committed
1618 1619 1620 1621

    HWND                    win_handle;
} IWineD3DSwapChainImpl;

1622
extern const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl;
Oliver Stieber's avatar
Oliver Stieber committed
1623

1624 1625
WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface);

1626 1627 1628
/*****************************************************************************
 * Utility function prototypes 
 */
1629 1630

/* Trace routines */
1631
const char* debug_d3dformat(WINED3DFORMAT fmt);
1632
const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype);
1633
const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res);
1634
const char* debug_d3dusage(DWORD usage);
1635
const char* debug_d3dusagequery(DWORD usagequery);
1636 1637
const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method);
const char* debug_d3ddecltype(WINED3DDECLTYPE type);
1638
const char* debug_d3ddeclusage(BYTE usage);
1639
const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType);
1640
const char* debug_d3drenderstate(DWORD state);
1641
const char* debug_d3dsamplerstate(DWORD state);
1642
const char* debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type);
1643
const char* debug_d3dtexturestate(DWORD state);
1644
const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype);
1645
const char* debug_d3dpool(WINED3DPOOL pool);
1646
const char *debug_fbostatus(GLenum status);
1647
const char *debug_glerror(GLenum error);
1648 1649
const char *debug_d3dbasis(WINED3DBASISTYPE basis);
const char *debug_d3ddegree(WINED3DDEGREETYPE order);
1650 1651 1652

/* Routines for GL <-> D3D values */
GLenum StencilOp(DWORD op);
1653
GLenum CompareFunc(DWORD func);
1654 1655
void   set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
void   set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx);
1656
void   set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype);
1657

1658
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
1659
GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
1660

1661 1662 1663
BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize);
BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize);

1664
/* Math utils */
1665
void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);
1666
unsigned int count_bits(unsigned int mask);
1667

1668 1669
/*****************************************************************************
 * To enable calling of inherited functions, requires prototypes 
1670 1671
 *
 * Note: Only require classes which are subclassed, ie resource, basetexture, 
1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685
 */
    /*** IUnknown methods ***/
    extern HRESULT WINAPI IWineD3DResourceImpl_QueryInterface(IWineD3DResource *iface, REFIID riid, void** ppvObject);
    extern ULONG WINAPI IWineD3DResourceImpl_AddRef(IWineD3DResource *iface);
    extern ULONG WINAPI IWineD3DResourceImpl_Release(IWineD3DResource *iface);
    /*** IWineD3DResource methods ***/
    extern HRESULT WINAPI IWineD3DResourceImpl_GetParent(IWineD3DResource *iface, IUnknown **pParent);
    extern HRESULT WINAPI IWineD3DResourceImpl_GetDevice(IWineD3DResource *iface, IWineD3DDevice ** ppDevice);
    extern HRESULT WINAPI IWineD3DResourceImpl_SetPrivateData(IWineD3DResource *iface, REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags);
    extern HRESULT WINAPI IWineD3DResourceImpl_GetPrivateData(IWineD3DResource *iface, REFGUID  refguid, void * pData, DWORD * pSizeOfData);
    extern HRESULT WINAPI IWineD3DResourceImpl_FreePrivateData(IWineD3DResource *iface, REFGUID  refguid);
    extern DWORD WINAPI IWineD3DResourceImpl_SetPriority(IWineD3DResource *iface, DWORD  PriorityNew);
    extern DWORD WINAPI IWineD3DResourceImpl_GetPriority(IWineD3DResource *iface);
    extern void WINAPI IWineD3DResourceImpl_PreLoad(IWineD3DResource *iface);
1686
    extern void WINAPI IWineD3DResourceImpl_UnLoad(IWineD3DResource *iface);
1687
    extern WINED3DRESOURCETYPE WINAPI IWineD3DResourceImpl_GetType(IWineD3DResource *iface);
1688 1689
    /*** class static members ***/
    void IWineD3DResourceImpl_CleanUp(IWineD3DResource *iface);
1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703

    /*** IUnknown methods ***/
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_QueryInterface(IWineD3DBaseTexture *iface, REFIID riid, void** ppvObject);
    extern ULONG WINAPI IWineD3DBaseTextureImpl_AddRef(IWineD3DBaseTexture *iface);
    extern ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface);
    /*** IWineD3DResource methods ***/
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_GetParent(IWineD3DBaseTexture *iface, IUnknown **pParent);
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_GetDevice(IWineD3DBaseTexture *iface, IWineD3DDevice ** ppDevice);
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_SetPrivateData(IWineD3DBaseTexture *iface, REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags);
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_GetPrivateData(IWineD3DBaseTexture *iface, REFGUID  refguid, void * pData, DWORD * pSizeOfData);
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_FreePrivateData(IWineD3DBaseTexture *iface, REFGUID  refguid);
    extern DWORD WINAPI IWineD3DBaseTextureImpl_SetPriority(IWineD3DBaseTexture *iface, DWORD  PriorityNew);
    extern DWORD WINAPI IWineD3DBaseTextureImpl_GetPriority(IWineD3DBaseTexture *iface);
    extern void WINAPI IWineD3DBaseTextureImpl_PreLoad(IWineD3DBaseTexture *iface);
1704
    extern void WINAPI IWineD3DBaseTextureImpl_UnLoad(IWineD3DBaseTexture *iface);
1705
    extern WINED3DRESOURCETYPE WINAPI IWineD3DBaseTextureImpl_GetType(IWineD3DBaseTexture *iface);
1706 1707 1708 1709
    /*** IWineD3DBaseTexture methods ***/
    extern DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD(IWineD3DBaseTexture *iface, DWORD LODNew);
    extern DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD(IWineD3DBaseTexture *iface);
    extern DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface);
1710 1711
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType);
    extern WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWineD3DBaseTexture *iface);
1712 1713 1714
    extern void WINAPI IWineD3DBaseTextureImpl_GenerateMipSubLevels(IWineD3DBaseTexture *iface);
    extern BOOL WINAPI IWineD3DBaseTextureImpl_SetDirty(IWineD3DBaseTexture *iface, BOOL);
    extern BOOL WINAPI IWineD3DBaseTextureImpl_GetDirty(IWineD3DBaseTexture *iface);
1715

1716
    extern BYTE* WINAPI IWineD3DVertexBufferImpl_GetMemory(IWineD3DVertexBuffer* iface, DWORD iOffset, GLint *vbo);
1717
    extern HRESULT WINAPI IWineD3DVertexBufferImpl_ReleaseMemory(IWineD3DVertexBuffer* iface);
1718 1719
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface);
    extern HRESULT WINAPI IWineD3DBaseTextureImpl_UnBindTexture(IWineD3DBaseTexture *iface);
1720
    extern void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface, const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]);
1721 1722
    /*** class static members ***/
    void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface);
1723

1724 1725
typedef void (*SHADER_HANDLER) (struct SHADER_OPCODE_ARG*);

1726 1727 1728 1729
/* Struct to maintain a list of GLSL shader programs and their associated pixel and
 * vertex shaders.  A list of this type is maintained on the DeviceImpl, and is only
 * used if the user is using GLSL shaders. */
struct glsl_shader_prog_link {
1730 1731
    struct list             vshader_entry;
    struct list             pshader_entry;
1732
    GLhandleARB             programId;
1733 1734
    GLhandleARB             *vuniformF_locations;
    GLhandleARB             *puniformF_locations;
1735 1736
    GLhandleARB             vuniformI_locations[MAX_CONST_I];
    GLhandleARB             puniformI_locations[MAX_CONST_I];
1737 1738 1739 1740 1741 1742 1743
    GLhandleARB             posFixup_location;
    GLhandleARB             bumpenvmat_location;
    GLhandleARB             luminancescale_location;
    GLhandleARB             luminanceoffset_location;
    GLhandleARB             srgb_comparison_location;
    GLhandleARB             srgb_mul_low_location;
    GLhandleARB             ycorrection_location;
1744 1745
    GLhandleARB             vshader;
    GLhandleARB             pshader;
1746 1747
};

1748 1749 1750 1751 1752
typedef struct {
    GLhandleARB vshader;
    GLhandleARB pshader;
} glsl_program_key_t;

1753 1754 1755 1756
/* TODO: Make this dynamic, based on shader limits ? */
#define MAX_REG_ADDR 1
#define MAX_REG_TEMP 32
#define MAX_REG_TEXCRD 8
1757 1758
#define MAX_REG_INPUT 12
#define MAX_REG_OUTPUT 12
1759 1760
#define MAX_CONST_I 16
#define MAX_CONST_B 16
1761

1762 1763 1764 1765
/* FIXME: This needs to go up to 2048 for
 * Shader model 3 according to msdn (and for software shaders) */
#define MAX_LABELS 16

1766 1767 1768 1769 1770
typedef struct semantic {
    DWORD usage;
    DWORD reg;
} semantic;

1771 1772 1773 1774 1775 1776
typedef struct local_constant {
    struct list entry;
    unsigned int idx;
    DWORD value[4];
} local_constant;

1777
typedef struct shader_reg_maps {
1778

1779 1780 1781
    char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
    char temporary[MAX_REG_TEMP];           /* pixel, vertex */
    char address[MAX_REG_ADDR];             /* vertex */
1782 1783
    char packed_input[MAX_REG_INPUT];       /* pshader >= 3.0 */
    char packed_output[MAX_REG_OUTPUT];     /* vertex >= 3.0 */
1784
    char attributes[MAX_ATTRIBS];           /* vertex */
1785
    char labels[MAX_LABELS];                /* pixel, vertex */
1786
    DWORD texcoord_mask[MAX_REG_TEXCRD];    /* vertex < 3.0 */
1787

1788 1789
    /* Sampler usage tokens 
     * Use 0 as default (bit 31 is always 1 on a valid token) */
1790
    DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
1791
    char bumpmat, luminanceparams;
1792
    char usesnrm, vpos, usesdsy;
1793
    char usesrelconstF;
1794

1795 1796
    /* Whether or not loops are used in this shader, and nesting depth */
    unsigned loop_depth;
1797

1798 1799 1800
    /* Whether or not this shader uses fog */
    char fog;

1801 1802
} shader_reg_maps;

1803 1804 1805
#define SHADER_PGMSIZE 65535
typedef struct SHADER_BUFFER {
    char* buffer;
1806
    unsigned int bsize;
1807
    unsigned int lineNo;
1808
    BOOL newline;
1809
} SHADER_BUFFER;
1810

1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823
/* Undocumented opcode controls */
#define INST_CONTROLS_SHIFT 16
#define INST_CONTROLS_MASK 0x00ff0000

typedef enum COMPARISON_TYPE {
    COMPARISON_GT = 1,
    COMPARISON_EQ = 2,
    COMPARISON_GE = 3,
    COMPARISON_LT = 4,
    COMPARISON_NE = 5,
    COMPARISON_LE = 6
} COMPARISON_TYPE;

1824 1825 1826 1827
typedef struct SHADER_OPCODE {
    unsigned int  opcode;
    const char*   name;
    const char*   glname;
1828
    char          dst_token;
1829
    CONST UINT    num_params;
1830
    SHADER_HANDLER hw_fct;
1831
    SHADER_HANDLER hw_glsl_fct;
1832 1833 1834 1835
    DWORD         min_version;
    DWORD         max_version;
} SHADER_OPCODE;

1836 1837
typedef struct SHADER_OPCODE_ARG {
    IWineD3DBaseShader* shader;
1838
    shader_reg_maps* reg_maps;
1839
    CONST SHADER_OPCODE* opcode;
1840
    DWORD opcode_token;
1841
    DWORD dst;
1842
    DWORD dst_addr;
1843
    DWORD predicate;
1844
    DWORD src[4];
1845
    DWORD src_addr[4];
1846 1847
    SHADER_BUFFER* buffer;
} SHADER_OPCODE_ARG;
1848

1849 1850
typedef struct SHADER_LIMITS {
    unsigned int temporary;
1851 1852
    unsigned int texcoord;
    unsigned int sampler;
1853 1854 1855 1856
    unsigned int constant_int;
    unsigned int constant_float;
    unsigned int constant_bool;
    unsigned int address;
1857 1858
    unsigned int packed_output;
    unsigned int packed_input;
1859
    unsigned int attributes;
1860
    unsigned int label;
1861 1862
} SHADER_LIMITS;

1863 1864 1865 1866 1867 1868 1869
/** Keeps track of details for TEX_M#x# shader opcodes which need to 
    maintain state information between multiple codes */
typedef struct SHADER_PARSE_STATE {
    unsigned int current_row;
    DWORD texcoord_w[2];
} SHADER_PARSE_STATE;

1870 1871 1872 1873 1874 1875
#ifdef __GNUC__
#define PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
#else
#define PRINTF_ATTR(fmt,args)
#endif

1876 1877 1878 1879
/* Base Shader utility functions. 
 * (may move callers into the same file in the future) */
extern int shader_addline(
    SHADER_BUFFER* buffer,
1880
    const char* fmt, ...) PRINTF_ATTR(2,3);
1881

1882 1883 1884 1885
extern const SHADER_OPCODE* shader_get_opcode(
    IWineD3DBaseShader *iface, 
    const DWORD code);

1886 1887
void delete_glsl_program_entry(IWineD3DDevice *iface, struct glsl_shader_prog_link *entry);

1888 1889 1890 1891 1892 1893 1894 1895 1896 1897
/* Vertex shader utility functions */
extern BOOL vshader_get_input(
    IWineD3DVertexShader* iface,
    BYTE usage_req, BYTE usage_idx_req,
    unsigned int* regnum);

extern BOOL vshader_input_is_color(
    IWineD3DVertexShader* iface,
    unsigned int regnum);

1898 1899
extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object);

1900 1901
/* ARB_[vertex/fragment]_program helper functions */
extern void shader_arb_load_constants(
1902
    IWineD3DDevice* device,
1903 1904 1905
    char usePixelShader,
    char useVertexShader);

1906 1907 1908
/* ARB shader program Prototypes */
extern void shader_hw_def(SHADER_OPCODE_ARG *arg);

1909
/* ARB pixel shader prototypes */
1910
extern void pshader_hw_bem(SHADER_OPCODE_ARG* arg);
1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924
extern void pshader_hw_cnd(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_cmp(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texbem(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg);
1925
extern void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg);
1926
extern void pshader_hw_texkill(SHADER_OPCODE_ARG* arg);
1927 1928 1929 1930
extern void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg);
1931
extern void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg);
1932
extern void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg);
1933

1934 1935
/* ARB vertex / pixel shader common prototypes */
extern void shader_hw_nrm(SHADER_OPCODE_ARG* arg);
1936
extern void shader_hw_sincos(SHADER_OPCODE_ARG* arg);
1937
extern void shader_hw_mnxn(SHADER_OPCODE_ARG* arg);
1938

1939 1940
/* ARB vertex shader prototypes */
extern void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg);
1941
extern void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg);
1942

1943 1944
/* GLSL helper functions */
extern void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG *arg);
1945
extern void shader_glsl_load_constants(
1946
    IWineD3DDevice* device,
1947 1948
    char usePixelShader,
    char useVertexShader);
1949

1950
/** The following translate DirectX pixel/vertex shader opcodes to GLSL lines */
1951
extern void shader_glsl_cross(SHADER_OPCODE_ARG* arg);
1952 1953 1954 1955 1956 1957 1958 1959
extern void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_arith(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_mov(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_mad(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_lrp(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_dot(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_rcp(SHADER_OPCODE_ARG* arg);
1960
extern void shader_glsl_rsq(SHADER_OPCODE_ARG* arg);
1961 1962 1963
extern void shader_glsl_cnd(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_compare(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_def(SHADER_OPCODE_ARG* arg);
1964 1965
extern void shader_glsl_defi(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_defb(SHADER_OPCODE_ARG* arg);
1966
extern void shader_glsl_expp(SHADER_OPCODE_ARG* arg);
1967
extern void shader_glsl_cmp(SHADER_OPCODE_ARG* arg);
1968 1969 1970 1971
extern void shader_glsl_lit(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_dst(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_sincos(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_loop(SHADER_OPCODE_ARG* arg);
1972 1973 1974 1975 1976 1977 1978
extern void shader_glsl_end(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_if(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_ifc(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_else(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_break(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_breakc(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_rep(SHADER_OPCODE_ARG* arg);
1979 1980 1981
extern void shader_glsl_call(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_label(SHADER_OPCODE_ARG* arg);
1982
extern void shader_glsl_pow(SHADER_OPCODE_ARG* arg);
1983
extern void shader_glsl_log(SHADER_OPCODE_ARG* arg);
H. Verbeet's avatar
H. Verbeet committed
1984
extern void shader_glsl_texldl(SHADER_OPCODE_ARG* arg);
1985

1986 1987 1988
/** GLSL Pixel Shader Prototypes */
extern void pshader_glsl_tex(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg);
1989 1990 1991 1992
extern void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg);
1993 1994
extern void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg);
1995
extern void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg);
1996
extern void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg);
1997 1998
extern void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg);
1999 2000 2001
extern void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg);
2002
extern void pshader_glsl_bem(SHADER_OPCODE_ARG* arg);
2003 2004 2005
extern void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg);
extern void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg);
2006
extern void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg);
2007 2008
extern void pshader_glsl_input_pack(
   SHADER_BUFFER* buffer,
2009 2010
   semantic* semantics_out,
   IWineD3DPixelShader *iface);
2011

2012 2013 2014 2015 2016
/*****************************************************************************
 * IDirect3DBaseShader implementation structure
 */
typedef struct IWineD3DBaseShaderClass
{
2017
    LONG                            ref;
2018 2019
    DWORD                           hex_version;
    SHADER_LIMITS                   limits;
2020
    SHADER_PARSE_STATE              parse_state;
2021
    CONST SHADER_OPCODE             *shader_ins;
2022
    DWORD                          *function;
2023 2024
    UINT                            functionLength;
    GLuint                          prgId;
2025
    BOOL                            is_compiled;
2026
    UINT                            cur_loop_depth, cur_loop_regno;
2027
    BOOL                            load_local_constsF;
2028 2029 2030 2031

    /* Type of shader backend */
    int shader_mode;

2032 2033 2034
    /* Programs this shader is linked with */
    struct list linked_programs;

2035 2036 2037 2038
    /* Immediate constants (override global ones) */
    struct list constantsB;
    struct list constantsF;
    struct list constantsI;
2039
    shader_reg_maps reg_maps;
2040

2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051
    /* Pixel formats of sampled textures, for format conversion. This
     * represents the formats found during compilation, it is not initialized
     * on the first parser pass. It is needed to check if the shader
     * needs recompilation to adjust the format conversion
     */
    WINED3DFORMAT       sampled_format[MAX_COMBINED_SAMPLERS];
    UINT                sampled_samplers[MAX_COMBINED_SAMPLERS];
    UINT                num_sampled_samplers;

    UINT recompile_count;

2052 2053
    /* Pointer to the parent device */
    IWineD3DDevice *device;
2054
    struct list     shader_list_entry;
2055

2056 2057 2058 2059 2060 2061 2062 2063 2064 2065
} IWineD3DBaseShaderClass;

typedef struct IWineD3DBaseShaderImpl {
    /* IUnknown */
    const IWineD3DBaseShaderVtbl    *lpVtbl;

    /* IWineD3DBaseShader */
    IWineD3DBaseShaderClass         baseShader;
} IWineD3DBaseShaderImpl;

2066 2067 2068 2069
HRESULT  WINAPI IWineD3DBaseShaderImpl_QueryInterface(IWineD3DBaseShader *iface, REFIID riid, LPVOID *ppobj);
ULONG  WINAPI IWineD3DBaseShaderImpl_AddRef(IWineD3DBaseShader *iface);
ULONG  WINAPI IWineD3DBaseShaderImpl_Release(IWineD3DBaseShader *iface);

2070
extern HRESULT shader_get_registers_used(
2071 2072
    IWineD3DBaseShader *iface,
    shader_reg_maps* reg_maps,
2073 2074
    semantic* semantics_in,
    semantic* semantics_out,
2075 2076
    CONST DWORD* pToken,
    IWineD3DStateBlockImpl *stateBlock);
2077

2078 2079 2080
extern void shader_generate_glsl_declarations(
    IWineD3DBaseShader *iface,
    shader_reg_maps* reg_maps,
2081 2082
    SHADER_BUFFER* buffer,
    WineD3D_GL_Info* gl_info);
2083 2084 2085 2086

extern void shader_generate_arb_declarations(
    IWineD3DBaseShader *iface,
    shader_reg_maps* reg_maps,
2087 2088
    SHADER_BUFFER* buffer,
    WineD3D_GL_Info* gl_info);
2089

2090
extern void shader_generate_main(
2091 2092
    IWineD3DBaseShader *iface,
    SHADER_BUFFER* buffer,
2093
    shader_reg_maps* reg_maps,
2094 2095
    CONST DWORD* pFunction);

2096 2097 2098
extern void shader_dump_ins_modifiers(
    const DWORD output);

2099 2100 2101
extern void shader_dump_param(
    IWineD3DBaseShader *iface,
    const DWORD param,
2102
    const DWORD addr_token,
2103 2104
    int input);

2105 2106 2107 2108
extern void shader_trace_init(
    IWineD3DBaseShader *iface,
    const DWORD* pFunction);

2109 2110 2111 2112 2113 2114 2115 2116 2117 2118
extern int shader_get_param(
    IWineD3DBaseShader* iface,
    const DWORD* pToken,
    DWORD* param,
    DWORD* addr_token);

extern int shader_skip_unrecognized(
    IWineD3DBaseShader* iface,
    const DWORD* pToken);

2119 2120 2121 2122
extern void print_glsl_info_log(
    WineD3D_GL_Info *gl_info,
    GLhandleARB obj);

2123
static inline int shader_get_regtype(const DWORD param) {
2124 2125
    return (((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) |
            ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2));
2126 2127
}

2128 2129 2130 2131
static inline int shader_get_writemask(const DWORD param) {
    return param & WINED3DSP_WRITEMASK_ALL;
}

2132 2133
extern unsigned int shader_get_float_offset(const DWORD reg);

2134
static inline BOOL shader_is_pshader_version(DWORD token) {
2135 2136 2137
    return 0xFFFF0000 == (token & 0xFFFF0000);
}

2138
static inline BOOL shader_is_vshader_version(DWORD token) {
2139 2140 2141
    return 0xFFFE0000 == (token & 0xFFFF0000);
}

2142
static inline BOOL shader_is_comment(DWORD token) {
2143
    return WINED3DSIO_COMMENT == (token & WINED3DSI_OPCODE_MASK);
2144 2145
}

2146 2147
static inline BOOL shader_is_scalar(DWORD param) {
    DWORD reg_type = shader_get_regtype(param);
2148
    DWORD reg_num;
2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164

    switch (reg_type) {
        case WINED3DSPR_RASTOUT:
            if ((param & WINED3DSP_REGNUM_MASK) != 0) {
                /* oFog & oPts */
                return TRUE;
            }
            /* oPos */
            return FALSE;

        case WINED3DSPR_DEPTHOUT:   /* oDepth */
        case WINED3DSPR_CONSTBOOL:  /* b# */
        case WINED3DSPR_LOOP:       /* aL */
        case WINED3DSPR_PREDICATE:  /* p0 */
            return TRUE;

2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175
        case WINED3DSPR_MISCTYPE:
            reg_num = param & WINED3DSP_REGNUM_MASK;
            switch(reg_num) {
                case 0: /* vPos */
                    return FALSE;
                case 1: /* vFace */
                    return TRUE;
                default:
                    return FALSE;
            }

2176 2177 2178 2179 2180
        default:
            return FALSE;
    }
}

2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191
static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD reg) {
    local_constant* lconst;

    if(This->baseShader.load_local_constsF) return FALSE;
    LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
        if(lconst->idx == reg) return TRUE;
    }
    return FALSE;

}

2192 2193 2194 2195 2196 2197
/* Internally used shader constants. Applications can use constants 0 to GL_LIMITS(vshader_constantsF) - 1,
 * so upload them above that
 */
#define ARB_SHADER_PRIVCONST_BASE GL_LIMITS(vshader_constantsF)
#define ARB_SHADER_PRIVCONST_POS ARB_SHADER_PRIVCONST_BASE + 0

2198 2199 2200
/*****************************************************************************
 * IDirect3DVertexShader implementation structure
 */
2201 2202
typedef struct IWineD3DVertexShaderImpl {
    /* IUnknown parts*/   
2203
    const IWineD3DVertexShaderVtbl *lpVtbl;
2204

2205 2206
    /* IWineD3DBaseShader */
    IWineD3DBaseShaderClass     baseShader;
2207

2208
    /* IWineD3DVertexShaderImpl */
2209
    IUnknown                    *parent;
2210

2211
    DWORD                       usage;
2212

2213
    /* Vertex shader input and output semantics */
2214 2215
    semantic semantics_in [MAX_ATTRIBS];
    semantic semantics_out [MAX_REG_OUTPUT];
2216

2217 2218 2219 2220
    /* Ordered array of attributes that are swizzled */
    attrib_declaration          swizzled_attribs [MAX_ATTRIBS];
    UINT                        num_swizzled_attribs;

2221
    /* run time datas...  */
2222
    VSHADERDATA                *data;
2223 2224 2225
    UINT                       min_rel_offset, max_rel_offset;
    UINT                       rel_offset;

2226
    UINT                       recompile_count;
2227 2228 2229 2230 2231 2232
#if 0 /* needs reworking */
    /* run time datas */
    VSHADERINPUTDATA input;
    VSHADEROUTPUTDATA output;
#endif
} IWineD3DVertexShaderImpl;
2233
extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[];
2234
extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
2235 2236 2237 2238

/*****************************************************************************
 * IDirect3DPixelShader implementation structure
 */
2239 2240 2241 2242 2243 2244 2245

enum vertexprocessing_mode {
    fixedfunction,
    vertexshader,
    pretransformed
};

2246
typedef struct IWineD3DPixelShaderImpl {
2247
    /* IUnknown parts */
2248
    const IWineD3DPixelShaderVtbl *lpVtbl;
2249

2250 2251 2252 2253
    /* IWineD3DBaseShader */
    IWineD3DBaseShaderClass     baseShader;

    /* IWineD3DPixelShaderImpl */
2254 2255
    IUnknown                   *parent;

2256
    /* Pixel shader input semantics */
2257
    semantic semantics_in [MAX_REG_INPUT];
2258
    DWORD                 input_reg_map[MAX_REG_INPUT];
2259
    BOOL                  input_reg_used[MAX_REG_INPUT];
2260

2261 2262 2263
    /* run time data */
    PSHADERDATA                *data;

2264 2265 2266
    /* Some information about the shader behavior */
    char                        needsbumpmat;
    UINT                        bumpenvmatconst;
2267
    UINT                        luminanceconst;
2268 2269 2270 2271
    char                        srgb_enabled;
    char                        srgb_mode_hardcoded;
    UINT                        srgb_low_const;
    UINT                        srgb_cmp_const;
2272 2273 2274
    char                        vpos_uniform;
    BOOL                        render_offscreen;
    UINT                        height;
2275
    enum vertexprocessing_mode  vertexprocessing;
2276

2277 2278 2279 2280 2281
#if 0 /* needs reworking */
    PSHADERINPUTDATA input;
    PSHADEROUTPUTDATA output;
#endif
} IWineD3DPixelShaderImpl;
2282

2283
extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
2284
extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
2285

2286 2287 2288 2289 2290 2291 2292
/* sRGB correction constants */
static const float srgb_cmp = 0.0031308;
static const float srgb_mul_low = 12.92;
static const float srgb_pow = 0.41666;
static const float srgb_mul_high = 1.055;
static const float srgb_sub_high = 0.055;

2293 2294 2295 2296 2297 2298 2299
/*****************************************************************************
 * IWineD3DPalette implementation structure
 */
struct IWineD3DPaletteImpl {
    /* IUnknown parts */
    const IWineD3DPaletteVtbl  *lpVtbl;
    LONG                       ref;
2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311

    IUnknown                   *parent;
    IWineD3DDeviceImpl         *wineD3DDevice;

    /* IWineD3DPalette */
    HPALETTE                   hpal;
    WORD                       palVersion;     /*|               */
    WORD                       palNumEntries;  /*|  LOGPALETTE   */
    PALETTEENTRY               palents[256];   /*|               */
    /* This is to store the palette in 'screen format' */
    int                        screen_palents[256];
    DWORD                      Flags;
2312 2313 2314
};

extern const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl;
2315
DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags);
2316

2317 2318 2319
/* DirectDraw utility functions */
extern WINED3DFORMAT pixelformat_for_depth(DWORD depth);

2320 2321 2322 2323 2324 2325 2326
/*****************************************************************************
 * Pixel format management
 */
typedef struct {
    WINED3DFORMAT           format;
    DWORD                   alphaMask, redMask, greenMask, blueMask;
    UINT                    bpp;
2327
    short                   depthSize, stencilSize;
2328
    BOOL                    isFourcc;
2329 2330 2331
} StaticPixelFormatDesc;

const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt,
2332
        WineD3D_GL_Info *gl_info,
2333
        const GlPixelFormatDesc **glDesc);
2334

2335
static inline BOOL use_vs(IWineD3DDeviceImpl *device) {
2336 2337 2338 2339 2340 2341
    return (device->vs_selected_mode != SHADER_NONE
            && device->stateBlock->vertexShader
            && ((IWineD3DVertexShaderImpl *)device->stateBlock->vertexShader)->baseShader.function
            && !device->strided_streams.u.s.position_transformed);
}

2342
static inline BOOL use_ps(IWineD3DDeviceImpl *device) {
2343 2344 2345 2346 2347
    return (device->ps_selected_mode != SHADER_NONE
            && device->stateBlock->pixelShader
            && ((IWineD3DPixelShaderImpl *)device->stateBlock->pixelShader)->baseShader.function);
}

2348
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
2349
        IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip);
2350

2351
#endif