ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

stateblock.c
Go to the documentation of this file.
00001 /*
00002  * state block implementation
00003  *
00004  * Copyright 2002 Raphael Junqueira
00005  * Copyright 2004 Jason Edmeades
00006  * Copyright 2005 Oliver Stieber
00007  * Copyright 2007 Stefan Dösinger for CodeWeavers
00008  * Copyright 2009 Henri Verbeet for CodeWeavers
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00023  */
00024 
00025 #include "config.h"
00026 #include "wined3d_private.h"
00027 
00028 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
00029 
00030 static const DWORD pixel_states_render[] =
00031 {
00032     WINED3D_RS_ALPHABLENDENABLE,
00033     WINED3D_RS_ALPHAFUNC,
00034     WINED3D_RS_ALPHAREF,
00035     WINED3D_RS_ALPHATESTENABLE,
00036     WINED3D_RS_ANTIALIASEDLINEENABLE,
00037     WINED3D_RS_BLENDFACTOR,
00038     WINED3D_RS_BLENDOP,
00039     WINED3D_RS_BLENDOPALPHA,
00040     WINED3D_RS_CCW_STENCILFAIL,
00041     WINED3D_RS_CCW_STENCILPASS,
00042     WINED3D_RS_CCW_STENCILZFAIL,
00043     WINED3D_RS_COLORWRITEENABLE,
00044     WINED3D_RS_COLORWRITEENABLE1,
00045     WINED3D_RS_COLORWRITEENABLE2,
00046     WINED3D_RS_COLORWRITEENABLE3,
00047     WINED3D_RS_DEPTHBIAS,
00048     WINED3D_RS_DESTBLEND,
00049     WINED3D_RS_DESTBLENDALPHA,
00050     WINED3D_RS_DITHERENABLE,
00051     WINED3D_RS_FILLMODE,
00052     WINED3D_RS_FOGDENSITY,
00053     WINED3D_RS_FOGEND,
00054     WINED3D_RS_FOGSTART,
00055     WINED3D_RS_LASTPIXEL,
00056     WINED3D_RS_SCISSORTESTENABLE,
00057     WINED3D_RS_SEPARATEALPHABLENDENABLE,
00058     WINED3D_RS_SHADEMODE,
00059     WINED3D_RS_SLOPESCALEDEPTHBIAS,
00060     WINED3D_RS_SRCBLEND,
00061     WINED3D_RS_SRCBLENDALPHA,
00062     WINED3D_RS_SRGBWRITEENABLE,
00063     WINED3D_RS_STENCILENABLE,
00064     WINED3D_RS_STENCILFAIL,
00065     WINED3D_RS_STENCILFUNC,
00066     WINED3D_RS_STENCILMASK,
00067     WINED3D_RS_STENCILPASS,
00068     WINED3D_RS_STENCILREF,
00069     WINED3D_RS_STENCILWRITEMASK,
00070     WINED3D_RS_STENCILZFAIL,
00071     WINED3D_RS_TEXTUREFACTOR,
00072     WINED3D_RS_TWOSIDEDSTENCILMODE,
00073     WINED3D_RS_WRAP0,
00074     WINED3D_RS_WRAP1,
00075     WINED3D_RS_WRAP10,
00076     WINED3D_RS_WRAP11,
00077     WINED3D_RS_WRAP12,
00078     WINED3D_RS_WRAP13,
00079     WINED3D_RS_WRAP14,
00080     WINED3D_RS_WRAP15,
00081     WINED3D_RS_WRAP2,
00082     WINED3D_RS_WRAP3,
00083     WINED3D_RS_WRAP4,
00084     WINED3D_RS_WRAP5,
00085     WINED3D_RS_WRAP6,
00086     WINED3D_RS_WRAP7,
00087     WINED3D_RS_WRAP8,
00088     WINED3D_RS_WRAP9,
00089     WINED3D_RS_ZENABLE,
00090     WINED3D_RS_ZFUNC,
00091     WINED3D_RS_ZWRITEENABLE,
00092 };
00093 
00094 static const DWORD pixel_states_texture[] =
00095 {
00096     WINED3D_TSS_ALPHA_ARG0,
00097     WINED3D_TSS_ALPHA_ARG1,
00098     WINED3D_TSS_ALPHA_ARG2,
00099     WINED3D_TSS_ALPHA_OP,
00100     WINED3D_TSS_BUMPENV_LOFFSET,
00101     WINED3D_TSS_BUMPENV_LSCALE,
00102     WINED3D_TSS_BUMPENV_MAT00,
00103     WINED3D_TSS_BUMPENV_MAT01,
00104     WINED3D_TSS_BUMPENV_MAT10,
00105     WINED3D_TSS_BUMPENV_MAT11,
00106     WINED3D_TSS_COLOR_ARG0,
00107     WINED3D_TSS_COLOR_ARG1,
00108     WINED3D_TSS_COLOR_ARG2,
00109     WINED3D_TSS_COLOR_OP,
00110     WINED3D_TSS_RESULT_ARG,
00111     WINED3D_TSS_TEXCOORD_INDEX,
00112     WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS,
00113 };
00114 
00115 static const DWORD pixel_states_sampler[] =
00116 {
00117     WINED3D_SAMP_ADDRESS_U,
00118     WINED3D_SAMP_ADDRESS_V,
00119     WINED3D_SAMP_ADDRESS_W,
00120     WINED3D_SAMP_BORDER_COLOR,
00121     WINED3D_SAMP_MAG_FILTER,
00122     WINED3D_SAMP_MIN_FILTER,
00123     WINED3D_SAMP_MIP_FILTER,
00124     WINED3D_SAMP_MIPMAP_LOD_BIAS,
00125     WINED3D_SAMP_MAX_MIP_LEVEL,
00126     WINED3D_SAMP_MAX_ANISOTROPY,
00127     WINED3D_SAMP_SRGB_TEXTURE,
00128     WINED3D_SAMP_ELEMENT_INDEX,
00129 };
00130 
00131 static const DWORD vertex_states_render[] =
00132 {
00133     WINED3D_RS_ADAPTIVETESS_W,
00134     WINED3D_RS_ADAPTIVETESS_X,
00135     WINED3D_RS_ADAPTIVETESS_Y,
00136     WINED3D_RS_ADAPTIVETESS_Z,
00137     WINED3D_RS_AMBIENT,
00138     WINED3D_RS_AMBIENTMATERIALSOURCE,
00139     WINED3D_RS_CLIPPING,
00140     WINED3D_RS_CLIPPLANEENABLE,
00141     WINED3D_RS_COLORVERTEX,
00142     WINED3D_RS_CULLMODE,
00143     WINED3D_RS_DIFFUSEMATERIALSOURCE,
00144     WINED3D_RS_EMISSIVEMATERIALSOURCE,
00145     WINED3D_RS_ENABLEADAPTIVETESSELLATION,
00146     WINED3D_RS_FOGCOLOR,
00147     WINED3D_RS_FOGDENSITY,
00148     WINED3D_RS_FOGENABLE,
00149     WINED3D_RS_FOGEND,
00150     WINED3D_RS_FOGSTART,
00151     WINED3D_RS_FOGTABLEMODE,
00152     WINED3D_RS_FOGVERTEXMODE,
00153     WINED3D_RS_INDEXEDVERTEXBLENDENABLE,
00154     WINED3D_RS_LIGHTING,
00155     WINED3D_RS_LOCALVIEWER,
00156     WINED3D_RS_MAXTESSELLATIONLEVEL,
00157     WINED3D_RS_MINTESSELLATIONLEVEL,
00158     WINED3D_RS_MULTISAMPLEANTIALIAS,
00159     WINED3D_RS_MULTISAMPLEMASK,
00160     WINED3D_RS_NORMALDEGREE,
00161     WINED3D_RS_NORMALIZENORMALS,
00162     WINED3D_RS_PATCHEDGESTYLE,
00163     WINED3D_RS_POINTSCALE_A,
00164     WINED3D_RS_POINTSCALE_B,
00165     WINED3D_RS_POINTSCALE_C,
00166     WINED3D_RS_POINTSCALEENABLE,
00167     WINED3D_RS_POINTSIZE,
00168     WINED3D_RS_POINTSIZE_MAX,
00169     WINED3D_RS_POINTSIZE_MIN,
00170     WINED3D_RS_POINTSPRITEENABLE,
00171     WINED3D_RS_POSITIONDEGREE,
00172     WINED3D_RS_RANGEFOGENABLE,
00173     WINED3D_RS_SHADEMODE,
00174     WINED3D_RS_SPECULARENABLE,
00175     WINED3D_RS_SPECULARMATERIALSOURCE,
00176     WINED3D_RS_TWEENFACTOR,
00177     WINED3D_RS_VERTEXBLEND,
00178 };
00179 
00180 static const DWORD vertex_states_texture[] =
00181 {
00182     WINED3D_TSS_TEXCOORD_INDEX,
00183     WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS,
00184 };
00185 
00186 static const DWORD vertex_states_sampler[] =
00187 {
00188     WINED3D_SAMP_DMAP_OFFSET,
00189 };
00190 
00191 /* Allocates the correct amount of space for pixel and vertex shader constants,
00192  * along with their set/changed flags on the given stateblock object
00193  */
00194 static HRESULT stateblock_allocate_shader_constants(struct wined3d_stateblock *object)
00195 {
00196     struct wined3d_device *device = object->device;
00197 
00198     /* Allocate space for floating point constants */
00199     object->state.ps_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
00200             sizeof(float) * device->d3d_pshader_constantF * 4);
00201     if (!object->state.ps_consts_f) goto fail;
00202 
00203     object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
00204             sizeof(BOOL) * device->d3d_pshader_constantF);
00205     if (!object->changed.pixelShaderConstantsF) goto fail;
00206 
00207     object->state.vs_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
00208             sizeof(float) * device->d3d_vshader_constantF * 4);
00209     if (!object->state.vs_consts_f) goto fail;
00210 
00211     object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
00212             sizeof(BOOL) * device->d3d_vshader_constantF);
00213     if (!object->changed.vertexShaderConstantsF) goto fail;
00214 
00215     object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0,
00216             sizeof(DWORD) * device->d3d_vshader_constantF);
00217     if (!object->contained_vs_consts_f) goto fail;
00218 
00219     object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0,
00220             sizeof(DWORD) * device->d3d_pshader_constantF);
00221     if (!object->contained_ps_consts_f) goto fail;
00222 
00223     return WINED3D_OK;
00224 
00225 fail:
00226     ERR("Failed to allocate memory\n");
00227     HeapFree(GetProcessHeap(), 0, object->state.ps_consts_f);
00228     HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF);
00229     HeapFree(GetProcessHeap(), 0, object->state.vs_consts_f);
00230     HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF);
00231     HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f);
00232     HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f);
00233     return E_OUTOFMEMORY;
00234 }
00235 
00236 static inline void stateblock_set_bits(DWORD *map, UINT map_size)
00237 {
00238     DWORD mask = (1 << (map_size & 0x1f)) - 1;
00239     memset(map, 0xff, (map_size >> 5) * sizeof(*map));
00240     if (mask) map[map_size >> 5] = mask;
00241 }
00242 
00243 /* Set all members of a stateblock savedstate to the given value */
00244 static void stateblock_savedstates_set_all(struct wined3d_saved_states *states, DWORD vs_consts, DWORD ps_consts)
00245 {
00246     unsigned int i;
00247 
00248     /* Single values */
00249     states->primitive_type = 1;
00250     states->indices = 1;
00251     states->material = 1;
00252     states->viewport = 1;
00253     states->vertexDecl = 1;
00254     states->pixelShader = 1;
00255     states->vertexShader = 1;
00256     states->scissorRect = 1;
00257 
00258     /* Fixed size arrays */
00259     states->streamSource = 0xffff;
00260     states->streamFreq = 0xffff;
00261     states->textures = 0xfffff;
00262     stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1);
00263     stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1);
00264     for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff;
00265     for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3ffe;
00266     states->clipplane = 0xffffffff;
00267     states->pixelShaderConstantsB = 0xffff;
00268     states->pixelShaderConstantsI = 0xffff;
00269     states->vertexShaderConstantsB = 0xffff;
00270     states->vertexShaderConstantsI = 0xffff;
00271 
00272     /* Dynamically sized arrays */
00273     memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * ps_consts);
00274     memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * vs_consts);
00275 }
00276 
00277 static void stateblock_savedstates_set_pixel(struct wined3d_saved_states *states, const DWORD num_constants)
00278 {
00279     DWORD texture_mask = 0;
00280     WORD sampler_mask = 0;
00281     unsigned int i;
00282 
00283     states->pixelShader = 1;
00284 
00285     for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
00286     {
00287         DWORD rs = pixel_states_render[i];
00288         states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
00289     }
00290 
00291     for (i = 0; i < sizeof(pixel_states_texture) / sizeof(*pixel_states_texture); ++i)
00292         texture_mask |= 1 << pixel_states_texture[i];
00293     for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
00294     for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
00295         sampler_mask |= 1 << pixel_states_sampler[i];
00296     for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
00297     states->pixelShaderConstantsB = 0xffff;
00298     states->pixelShaderConstantsI = 0xffff;
00299 
00300     memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * num_constants);
00301 }
00302 
00303 static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *states, const DWORD num_constants)
00304 {
00305     DWORD texture_mask = 0;
00306     WORD sampler_mask = 0;
00307     unsigned int i;
00308 
00309     states->vertexDecl = 1;
00310     states->vertexShader = 1;
00311 
00312     for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
00313     {
00314         DWORD rs = vertex_states_render[i];
00315         states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
00316     }
00317 
00318     for (i = 0; i < sizeof(vertex_states_texture) / sizeof(*vertex_states_texture); ++i)
00319         texture_mask |= 1 << vertex_states_texture[i];
00320     for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
00321     for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
00322         sampler_mask |= 1 << vertex_states_sampler[i];
00323     for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
00324     states->vertexShaderConstantsB = 0xffff;
00325     states->vertexShaderConstantsI = 0xffff;
00326 
00327     memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * num_constants);
00328 }
00329 
00330 void stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
00331 {
00332     struct wined3d_device *device = stateblock->device;
00333     unsigned int i, j;
00334 
00335     for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i)
00336     {
00337         DWORD map = stateblock->changed.renderState[i];
00338         for (j = 0; map; map >>= 1, ++j)
00339         {
00340             if (!(map & 1)) continue;
00341 
00342             stateblock->contained_render_states[stateblock->num_contained_render_states] = (i << 5) | j;
00343             ++stateblock->num_contained_render_states;
00344         }
00345     }
00346 
00347     for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i)
00348     {
00349         DWORD map = stateblock->changed.transform[i];
00350         for (j = 0; map; map >>= 1, ++j)
00351         {
00352             if (!(map & 1)) continue;
00353 
00354             stateblock->contained_transform_states[stateblock->num_contained_transform_states] = (i << 5) | j;
00355             ++stateblock->num_contained_transform_states;
00356         }
00357     }
00358 
00359     for (i = 0; i < device->d3d_vshader_constantF; ++i)
00360     {
00361         if (stateblock->changed.vertexShaderConstantsF[i])
00362         {
00363             stateblock->contained_vs_consts_f[stateblock->num_contained_vs_consts_f] = i;
00364             ++stateblock->num_contained_vs_consts_f;
00365         }
00366     }
00367 
00368     for (i = 0; i < MAX_CONST_I; ++i)
00369     {
00370         if (stateblock->changed.vertexShaderConstantsI & (1 << i))
00371         {
00372             stateblock->contained_vs_consts_i[stateblock->num_contained_vs_consts_i] = i;
00373             ++stateblock->num_contained_vs_consts_i;
00374         }
00375     }
00376 
00377     for (i = 0; i < MAX_CONST_B; ++i)
00378     {
00379         if (stateblock->changed.vertexShaderConstantsB & (1 << i))
00380         {
00381             stateblock->contained_vs_consts_b[stateblock->num_contained_vs_consts_b] = i;
00382             ++stateblock->num_contained_vs_consts_b;
00383         }
00384     }
00385 
00386     for (i = 0; i < device->d3d_pshader_constantF; ++i)
00387     {
00388         if (stateblock->changed.pixelShaderConstantsF[i])
00389         {
00390             stateblock->contained_ps_consts_f[stateblock->num_contained_ps_consts_f] = i;
00391             ++stateblock->num_contained_ps_consts_f;
00392         }
00393     }
00394 
00395     for (i = 0; i < MAX_CONST_I; ++i)
00396     {
00397         if (stateblock->changed.pixelShaderConstantsI & (1 << i))
00398         {
00399             stateblock->contained_ps_consts_i[stateblock->num_contained_ps_consts_i] = i;
00400             ++stateblock->num_contained_ps_consts_i;
00401         }
00402     }
00403 
00404     for (i = 0; i < MAX_CONST_B; ++i)
00405     {
00406         if (stateblock->changed.pixelShaderConstantsB & (1 << i))
00407         {
00408             stateblock->contained_ps_consts_b[stateblock->num_contained_ps_consts_b] = i;
00409             ++stateblock->num_contained_ps_consts_b;
00410         }
00411     }
00412 
00413     for (i = 0; i < MAX_TEXTURES; ++i)
00414     {
00415         DWORD map = stateblock->changed.textureState[i];
00416 
00417         for(j = 0; map; map >>= 1, ++j)
00418         {
00419             if (!(map & 1)) continue;
00420 
00421             stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
00422             stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = j;
00423             ++stateblock->num_contained_tss_states;
00424         }
00425     }
00426 
00427     for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
00428     {
00429         DWORD map = stateblock->changed.samplerState[i];
00430 
00431         for (j = 0; map; map >>= 1, ++j)
00432         {
00433             if (!(map & 1)) continue;
00434 
00435             stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
00436             stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = j;
00437             ++stateblock->num_contained_sampler_states;
00438         }
00439     }
00440 }
00441 
00442 static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct list *light_map)
00443 {
00444     unsigned int i;
00445 
00446     for (i = 0; i < LIGHTMAP_SIZE; ++i)
00447     {
00448         const struct wined3d_light_info *src_light;
00449 
00450         LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry)
00451         {
00452             struct wined3d_light_info *dst_light = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_light));
00453 
00454             *dst_light = *src_light;
00455             list_add_tail(&stateblock->state.light_map[i], &dst_light->entry);
00456         }
00457     }
00458 }
00459 
00460 ULONG CDECL wined3d_stateblock_incref(struct wined3d_stateblock *stateblock)
00461 {
00462     ULONG refcount = InterlockedIncrement(&stateblock->ref);
00463 
00464     TRACE("%p increasing refcount to %u.\n", stateblock, refcount);
00465 
00466     return refcount;
00467 }
00468 
00469 void stateblock_unbind_resources(struct wined3d_stateblock *stateblock)
00470 {
00471     struct wined3d_state *state = &stateblock->state;
00472     struct wined3d_vertex_declaration *decl;
00473     struct wined3d_texture *texture;
00474     struct wined3d_buffer *buffer;
00475     struct wined3d_shader *shader;
00476     unsigned int i;
00477 
00478     if ((decl = state->vertex_declaration))
00479     {
00480         state->vertex_declaration = NULL;
00481         wined3d_vertex_declaration_decref(decl);
00482     }
00483 
00484     for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
00485     {
00486         if ((texture = state->textures[i]))
00487         {
00488             state->textures[i] = NULL;
00489             wined3d_texture_decref(texture);
00490         }
00491     }
00492 
00493     for (i = 0; i < MAX_STREAMS; ++i)
00494     {
00495         if ((buffer = state->streams[i].buffer))
00496         {
00497             state->streams[i].buffer = NULL;
00498             wined3d_buffer_decref(buffer);
00499         }
00500     }
00501 
00502     if ((buffer = state->index_buffer))
00503     {
00504         state->index_buffer = NULL;
00505         wined3d_buffer_decref(buffer);
00506     }
00507 
00508     if ((shader = state->vertex_shader))
00509     {
00510         state->vertex_shader = NULL;
00511         wined3d_shader_decref(shader);
00512     }
00513 
00514     if ((shader = state->pixel_shader))
00515     {
00516         state->pixel_shader = NULL;
00517         wined3d_shader_decref(shader);
00518     }
00519 }
00520 
00521 ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock)
00522 {
00523     ULONG refcount = InterlockedDecrement(&stateblock->ref);
00524 
00525     TRACE("%p decreasing refcount to %u\n", stateblock, refcount);
00526 
00527     if (!refcount)
00528     {
00529         int counter;
00530 
00531         stateblock_unbind_resources(stateblock);
00532 
00533         for (counter = 0; counter < LIGHTMAP_SIZE; ++counter)
00534         {
00535             struct list *e1, *e2;
00536             LIST_FOR_EACH_SAFE(e1, e2, &stateblock->state.light_map[counter])
00537             {
00538                 struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry);
00539                 list_remove(&light->entry);
00540                 HeapFree(GetProcessHeap(), 0, light);
00541             }
00542         }
00543 
00544         HeapFree(GetProcessHeap(), 0, stateblock->state.vs_consts_f);
00545         HeapFree(GetProcessHeap(), 0, stateblock->changed.vertexShaderConstantsF);
00546         HeapFree(GetProcessHeap(), 0, stateblock->state.ps_consts_f);
00547         HeapFree(GetProcessHeap(), 0, stateblock->changed.pixelShaderConstantsF);
00548         HeapFree(GetProcessHeap(), 0, stateblock->contained_vs_consts_f);
00549         HeapFree(GetProcessHeap(), 0, stateblock->contained_ps_consts_f);
00550         HeapFree(GetProcessHeap(), 0, stateblock);
00551     }
00552 
00553     return refcount;
00554 }
00555 
00556 static void wined3d_state_record_lights(struct wined3d_state *dst_state, const struct wined3d_state *src_state)
00557 {
00558     UINT i;
00559 
00560     /* Lights... For a recorded state block, we just had a chain of actions
00561      * to perform, so we need to walk that chain and update any actions which
00562      * differ. */
00563     for (i = 0; i < LIGHTMAP_SIZE; ++i)
00564     {
00565         struct list *e, *f;
00566         LIST_FOR_EACH(e, &dst_state->light_map[i])
00567         {
00568             BOOL updated = FALSE;
00569             struct wined3d_light_info *src = LIST_ENTRY(e, struct wined3d_light_info, entry), *realLight;
00570 
00571             /* Look up the light in the destination */
00572             LIST_FOR_EACH(f, &src_state->light_map[i])
00573             {
00574                 realLight = LIST_ENTRY(f, struct wined3d_light_info, entry);
00575                 if (realLight->OriginalIndex == src->OriginalIndex)
00576                 {
00577                     src->OriginalParms = realLight->OriginalParms;
00578 
00579                     if (realLight->glIndex == -1 && src->glIndex != -1)
00580                     {
00581                         /* Light disabled */
00582                         dst_state->lights[src->glIndex] = NULL;
00583                     }
00584                     else if (realLight->glIndex != -1 && src->glIndex == -1)
00585                     {
00586                         /* Light enabled */
00587                         dst_state->lights[realLight->glIndex] = src;
00588                     }
00589                     src->glIndex = realLight->glIndex;
00590                     updated = TRUE;
00591                     break;
00592                 }
00593             }
00594 
00595             if (!updated)
00596             {
00597                 /* This can happen if the light was originally created as a
00598                  * default light for SetLightEnable() while recording. */
00599                 WARN("Light %u in dst_state %p does not exist in src_state %p.\n",
00600                         src->OriginalIndex, dst_state, src_state);
00601 
00602                 src->OriginalParms = WINED3D_default_light;
00603                 if (src->glIndex != -1)
00604                 {
00605                     dst_state->lights[src->glIndex] = NULL;
00606                     src->glIndex = -1;
00607                 }
00608             }
00609         }
00610     }
00611 }
00612 
00613 HRESULT CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
00614 {
00615     const struct wined3d_state *src_state = &stateblock->device->stateBlock->state;
00616     unsigned int i;
00617     DWORD map;
00618 
00619     TRACE("stateblock %p.\n", stateblock);
00620 
00621     TRACE("Capturing state %p.\n", src_state);
00622 
00623     if (stateblock->changed.vertexShader && stateblock->state.vertex_shader != src_state->vertex_shader)
00624     {
00625         TRACE("Updating vertex shader from %p to %p\n",
00626                 stateblock->state.vertex_shader, src_state->vertex_shader);
00627 
00628         if (src_state->vertex_shader)
00629             wined3d_shader_incref(src_state->vertex_shader);
00630         if (stateblock->state.vertex_shader)
00631             wined3d_shader_decref(stateblock->state.vertex_shader);
00632         stateblock->state.vertex_shader = src_state->vertex_shader;
00633     }
00634 
00635     /* Vertex shader float constants. */
00636     for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i)
00637     {
00638         unsigned int idx = stateblock->contained_vs_consts_f[i];
00639 
00640         TRACE("Setting vs_consts_f[%u] to {%.8e, %.8e, %.8e, %.8e}.\n", idx,
00641                 src_state->vs_consts_f[idx * 4 + 0],
00642                 src_state->vs_consts_f[idx * 4 + 1],
00643                 src_state->vs_consts_f[idx * 4 + 2],
00644                 src_state->vs_consts_f[idx * 4 + 3]);
00645 
00646         stateblock->state.vs_consts_f[idx * 4 + 0] = src_state->vs_consts_f[idx * 4 + 0];
00647         stateblock->state.vs_consts_f[idx * 4 + 1] = src_state->vs_consts_f[idx * 4 + 1];
00648         stateblock->state.vs_consts_f[idx * 4 + 2] = src_state->vs_consts_f[idx * 4 + 2];
00649         stateblock->state.vs_consts_f[idx * 4 + 3] = src_state->vs_consts_f[idx * 4 + 3];
00650     }
00651 
00652     /* Vertex shader integer constants. */
00653     for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i)
00654     {
00655         unsigned int idx = stateblock->contained_vs_consts_i[i];
00656 
00657         TRACE("Setting vs_consts[%u] to {%d, %d, %d, %d}.\n", idx,
00658                 src_state->vs_consts_i[idx * 4 + 0],
00659                 src_state->vs_consts_i[idx * 4 + 1],
00660                 src_state->vs_consts_i[idx * 4 + 2],
00661                 src_state->vs_consts_i[idx * 4 + 3]);
00662 
00663         stateblock->state.vs_consts_i[idx * 4 + 0] = src_state->vs_consts_i[idx * 4 + 0];
00664         stateblock->state.vs_consts_i[idx * 4 + 1] = src_state->vs_consts_i[idx * 4 + 1];
00665         stateblock->state.vs_consts_i[idx * 4 + 2] = src_state->vs_consts_i[idx * 4 + 2];
00666         stateblock->state.vs_consts_i[idx * 4 + 3] = src_state->vs_consts_i[idx * 4 + 3];
00667     }
00668 
00669     /* Vertex shader boolean constants. */
00670     for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i)
00671     {
00672         unsigned int idx = stateblock->contained_vs_consts_b[i];
00673 
00674         TRACE("Setting vs_consts_b[%u] to %s.\n",
00675                 idx, src_state->vs_consts_b[idx] ? "TRUE" : "FALSE");
00676 
00677         stateblock->state.vs_consts_b[idx] = src_state->vs_consts_b[idx];
00678     }
00679 
00680     /* Pixel shader float constants. */
00681     for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i)
00682     {
00683         unsigned int idx = stateblock->contained_ps_consts_f[i];
00684 
00685         TRACE("Setting ps_consts_f[%u] to {%.8e, %.8e, %.8e, %.8e}.\n", idx,
00686                 src_state->ps_consts_f[idx * 4 + 0],
00687                 src_state->ps_consts_f[idx * 4 + 1],
00688                 src_state->ps_consts_f[idx * 4 + 2],
00689                 src_state->ps_consts_f[idx * 4 + 3]);
00690 
00691         stateblock->state.ps_consts_f[idx * 4 + 0] = src_state->ps_consts_f[idx * 4 + 0];
00692         stateblock->state.ps_consts_f[idx * 4 + 1] = src_state->ps_consts_f[idx * 4 + 1];
00693         stateblock->state.ps_consts_f[idx * 4 + 2] = src_state->ps_consts_f[idx * 4 + 2];
00694         stateblock->state.ps_consts_f[idx * 4 + 3] = src_state->ps_consts_f[idx * 4 + 3];
00695     }
00696 
00697     /* Pixel shader integer constants. */
00698     for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i)
00699     {
00700         unsigned int idx = stateblock->contained_ps_consts_i[i];
00701         TRACE("Setting ps_consts_i[%u] to {%d, %d, %d, %d}.\n", idx,
00702                 src_state->ps_consts_i[idx * 4 + 0],
00703                 src_state->ps_consts_i[idx * 4 + 1],
00704                 src_state->ps_consts_i[idx * 4 + 2],
00705                 src_state->ps_consts_i[idx * 4 + 3]);
00706 
00707         stateblock->state.ps_consts_i[idx * 4 + 0] = src_state->ps_consts_i[idx * 4 + 0];
00708         stateblock->state.ps_consts_i[idx * 4 + 1] = src_state->ps_consts_i[idx * 4 + 1];
00709         stateblock->state.ps_consts_i[idx * 4 + 2] = src_state->ps_consts_i[idx * 4 + 2];
00710         stateblock->state.ps_consts_i[idx * 4 + 3] = src_state->ps_consts_i[idx * 4 + 3];
00711     }
00712 
00713     /* Pixel shader boolean constants. */
00714     for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i)
00715     {
00716         unsigned int idx = stateblock->contained_ps_consts_b[i];
00717         TRACE("Setting ps_consts_b[%u] to %s.\n",
00718                 idx, src_state->ps_consts_b[idx] ? "TRUE" : "FALSE");
00719 
00720         stateblock->state.ps_consts_b[idx] = src_state->ps_consts_b[idx];
00721     }
00722 
00723     /* Others + Render & Texture */
00724     for (i = 0; i < stateblock->num_contained_transform_states; ++i)
00725     {
00726         enum wined3d_transform_state transform = stateblock->contained_transform_states[i];
00727 
00728         TRACE("Updating transform %#x.\n", transform);
00729 
00730         stateblock->state.transforms[transform] = src_state->transforms[transform];
00731     }
00732 
00733     if (stateblock->changed.primitive_type)
00734         stateblock->state.gl_primitive_type = src_state->gl_primitive_type;
00735 
00736     if (stateblock->changed.indices
00737             && ((stateblock->state.index_buffer != src_state->index_buffer)
00738                 || (stateblock->state.base_vertex_index != src_state->base_vertex_index)
00739                 || (stateblock->state.index_format != src_state->index_format)))
00740     {
00741         TRACE("Updating index buffer to %p, base vertex index to %d.\n",
00742                 src_state->index_buffer, src_state->base_vertex_index);
00743 
00744         if (src_state->index_buffer)
00745             wined3d_buffer_incref(src_state->index_buffer);
00746         if (stateblock->state.index_buffer)
00747             wined3d_buffer_decref(stateblock->state.index_buffer);
00748         stateblock->state.index_buffer = src_state->index_buffer;
00749         stateblock->state.base_vertex_index = src_state->base_vertex_index;
00750         stateblock->state.index_format = src_state->index_format;
00751     }
00752 
00753     if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration != src_state->vertex_declaration)
00754     {
00755         TRACE("Updating vertex declaration from %p to %p.\n",
00756                 stateblock->state.vertex_declaration, src_state->vertex_declaration);
00757 
00758         if (src_state->vertex_declaration)
00759                 wined3d_vertex_declaration_incref(src_state->vertex_declaration);
00760         if (stateblock->state.vertex_declaration)
00761                 wined3d_vertex_declaration_decref(stateblock->state.vertex_declaration);
00762         stateblock->state.vertex_declaration = src_state->vertex_declaration;
00763     }
00764 
00765     if (stateblock->changed.material
00766             && memcmp(&src_state->material, &stateblock->state.material, sizeof(stateblock->state.material)))
00767     {
00768         TRACE("Updating material.\n");
00769 
00770         stateblock->state.material = src_state->material;
00771     }
00772 
00773     if (stateblock->changed.viewport
00774             && memcmp(&src_state->viewport, &stateblock->state.viewport, sizeof(stateblock->state.viewport)))
00775     {
00776         TRACE("Updating viewport.\n");
00777 
00778         stateblock->state.viewport = src_state->viewport;
00779     }
00780 
00781     if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect,
00782             &stateblock->state.scissor_rect, sizeof(stateblock->state.scissor_rect)))
00783     {
00784         TRACE("Updating scissor rect.\n");
00785 
00786         stateblock->state.scissor_rect = src_state->scissor_rect;
00787     }
00788 
00789     map = stateblock->changed.streamSource;
00790     for (i = 0; map; map >>= 1, ++i)
00791     {
00792         if (!(map & 1)) continue;
00793 
00794         if (stateblock->state.streams[i].stride != src_state->streams[i].stride
00795                 || stateblock->state.streams[i].buffer != src_state->streams[i].buffer)
00796         {
00797             TRACE("Updating stream source %u to %p, stride to %u.\n",
00798                     i, src_state->streams[i].buffer,
00799                     src_state->streams[i].stride);
00800 
00801             stateblock->state.streams[i].stride = src_state->streams[i].stride;
00802             if (src_state->streams[i].buffer)
00803                     wined3d_buffer_incref(src_state->streams[i].buffer);
00804             if (stateblock->state.streams[i].buffer)
00805                     wined3d_buffer_decref(stateblock->state.streams[i].buffer);
00806             stateblock->state.streams[i].buffer = src_state->streams[i].buffer;
00807         }
00808     }
00809 
00810     map = stateblock->changed.streamFreq;
00811     for (i = 0; map; map >>= 1, ++i)
00812     {
00813         if (!(map & 1)) continue;
00814 
00815         if (stateblock->state.streams[i].frequency != src_state->streams[i].frequency
00816                 || stateblock->state.streams[i].flags != src_state->streams[i].flags)
00817         {
00818             TRACE("Updating stream frequency %u to %u flags to %#x.\n",
00819                     i, src_state->streams[i].frequency, src_state->streams[i].flags);
00820 
00821             stateblock->state.streams[i].frequency = src_state->streams[i].frequency;
00822             stateblock->state.streams[i].flags = src_state->streams[i].flags;
00823         }
00824     }
00825 
00826     map = stateblock->changed.clipplane;
00827     for (i = 0; map; map >>= 1, ++i)
00828     {
00829         if (!(map & 1)) continue;
00830 
00831         if (memcmp(src_state->clip_planes[i], stateblock->state.clip_planes[i], sizeof(*stateblock->state.clip_planes)))
00832         {
00833             TRACE("Updating clipplane %u.\n", i);
00834             memcpy(stateblock->state.clip_planes[i], src_state->clip_planes[i], sizeof(*stateblock->state.clip_planes));
00835         }
00836     }
00837 
00838     /* Render */
00839     for (i = 0; i < stateblock->num_contained_render_states; ++i)
00840     {
00841         enum wined3d_render_state rs = stateblock->contained_render_states[i];
00842 
00843         TRACE("Updating render state %#x to %u.\n", rs, src_state->render_states[rs]);
00844 
00845         stateblock->state.render_states[rs] = src_state->render_states[rs];
00846     }
00847 
00848     /* Texture states */
00849     for (i = 0; i < stateblock->num_contained_tss_states; ++i)
00850     {
00851         DWORD stage = stateblock->contained_tss_states[i].stage;
00852         DWORD state = stateblock->contained_tss_states[i].state;
00853 
00854         TRACE("Updating texturestage state %u, %u to %#x (was %#x).\n", stage, state,
00855                 src_state->texture_states[stage][state], stateblock->state.texture_states[stage][state]);
00856 
00857         stateblock->state.texture_states[stage][state] = src_state->texture_states[stage][state];
00858     }
00859 
00860     /* Samplers */
00861     map = stateblock->changed.textures;
00862     for (i = 0; map; map >>= 1, ++i)
00863     {
00864         if (!(map & 1)) continue;
00865 
00866         TRACE("Updating texture %u to %p (was %p).\n",
00867                 i, src_state->textures[i], stateblock->state.textures[i]);
00868 
00869         if (src_state->textures[i])
00870             wined3d_texture_incref(src_state->textures[i]);
00871         if (stateblock->state.textures[i])
00872             wined3d_texture_decref(stateblock->state.textures[i]);
00873         stateblock->state.textures[i] = src_state->textures[i];
00874     }
00875 
00876     for (i = 0; i < stateblock->num_contained_sampler_states; ++i)
00877     {
00878         DWORD stage = stateblock->contained_sampler_states[i].stage;
00879         DWORD state = stateblock->contained_sampler_states[i].state;
00880 
00881         TRACE("Updating sampler state %u, %u to %#x (was %#x).\n", stage, state,
00882                 src_state->sampler_states[stage][state], stateblock->state.sampler_states[stage][state]);
00883 
00884         stateblock->state.sampler_states[stage][state] = src_state->sampler_states[stage][state];
00885     }
00886 
00887     if (stateblock->changed.pixelShader && stateblock->state.pixel_shader != src_state->pixel_shader)
00888     {
00889         if (src_state->pixel_shader)
00890             wined3d_shader_incref(src_state->pixel_shader);
00891         if (stateblock->state.pixel_shader)
00892             wined3d_shader_decref(stateblock->state.pixel_shader);
00893         stateblock->state.pixel_shader = src_state->pixel_shader;
00894     }
00895 
00896     wined3d_state_record_lights(&stateblock->state, src_state);
00897 
00898     TRACE("Capture done.\n");
00899 
00900     return WINED3D_OK;
00901 }
00902 
00903 static void apply_lights(struct wined3d_device *device, const struct wined3d_state *state)
00904 {
00905     UINT i;
00906 
00907     for (i = 0; i < LIGHTMAP_SIZE; ++i)
00908     {
00909         struct list *e;
00910 
00911         LIST_FOR_EACH(e, &state->light_map[i])
00912         {
00913             const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry);
00914 
00915             wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms);
00916             wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1);
00917         }
00918     }
00919 }
00920 
00921 HRESULT CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
00922 {
00923     struct wined3d_device *device = stateblock->device;
00924     unsigned int i;
00925     DWORD map;
00926 
00927     TRACE("Applying stateblock %p of type %#x to device %p.\n",
00928             stateblock, stateblock->blockType, device);
00929 
00930     if (stateblock->changed.vertexShader)
00931         wined3d_device_set_vertex_shader(device, stateblock->state.vertex_shader);
00932 
00933     /* Vertex Shader Constants. */
00934     for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i)
00935     {
00936         wined3d_device_set_vs_consts_f(device, stateblock->contained_vs_consts_f[i],
00937                 stateblock->state.vs_consts_f + stateblock->contained_vs_consts_f[i] * 4, 1);
00938     }
00939     for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i)
00940     {
00941         wined3d_device_set_vs_consts_i(device, stateblock->contained_vs_consts_i[i],
00942                 stateblock->state.vs_consts_i + stateblock->contained_vs_consts_i[i] * 4, 1);
00943     }
00944     for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i)
00945     {
00946         wined3d_device_set_vs_consts_b(device, stateblock->contained_vs_consts_b[i],
00947                 stateblock->state.vs_consts_b + stateblock->contained_vs_consts_b[i], 1);
00948     }
00949 
00950     apply_lights(device, &stateblock->state);
00951 
00952     if (stateblock->changed.pixelShader)
00953         wined3d_device_set_pixel_shader(device, stateblock->state.pixel_shader);
00954 
00955     /* Pixel Shader Constants. */
00956     for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i)
00957     {
00958         wined3d_device_set_ps_consts_f(device, stateblock->contained_ps_consts_f[i],
00959                 stateblock->state.ps_consts_f + stateblock->contained_ps_consts_f[i] * 4, 1);
00960     }
00961     for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i)
00962     {
00963         wined3d_device_set_ps_consts_i(device, stateblock->contained_ps_consts_i[i],
00964                 stateblock->state.ps_consts_i + stateblock->contained_ps_consts_i[i] * 4, 1);
00965     }
00966     for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i)
00967     {
00968         wined3d_device_set_ps_consts_b(device, stateblock->contained_ps_consts_b[i],
00969                 stateblock->state.ps_consts_b + stateblock->contained_ps_consts_b[i], 1);
00970     }
00971 
00972     /* Render states. */
00973     for (i = 0; i < stateblock->num_contained_render_states; ++i)
00974     {
00975         wined3d_device_set_render_state(device, stateblock->contained_render_states[i],
00976                 stateblock->state.render_states[stateblock->contained_render_states[i]]);
00977     }
00978 
00979     /* Texture states. */
00980     for (i = 0; i < stateblock->num_contained_tss_states; ++i)
00981     {
00982         DWORD stage = stateblock->contained_tss_states[i].stage;
00983         DWORD state = stateblock->contained_tss_states[i].state;
00984 
00985         wined3d_device_set_texture_stage_state(device, stage, state, stateblock->state.texture_states[stage][state]);
00986     }
00987 
00988     /* Sampler states. */
00989     for (i = 0; i < stateblock->num_contained_sampler_states; ++i)
00990     {
00991         DWORD stage = stateblock->contained_sampler_states[i].stage;
00992         DWORD state = stateblock->contained_sampler_states[i].state;
00993         DWORD value = stateblock->state.sampler_states[stage][state];
00994 
00995         if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS;
00996         wined3d_device_set_sampler_state(device, stage, state, value);
00997     }
00998 
00999     /* Transform states. */
01000     for (i = 0; i < stateblock->num_contained_transform_states; ++i)
01001     {
01002         wined3d_device_set_transform(device, stateblock->contained_transform_states[i],
01003                 &stateblock->state.transforms[stateblock->contained_transform_states[i]]);
01004     }
01005 
01006     if (stateblock->changed.primitive_type)
01007     {
01008         stateblock->device->updateStateBlock->changed.primitive_type = TRUE;
01009         stateblock->device->updateStateBlock->state.gl_primitive_type = stateblock->state.gl_primitive_type;
01010     }
01011 
01012     if (stateblock->changed.indices)
01013     {
01014         wined3d_device_set_index_buffer(device, stateblock->state.index_buffer, stateblock->state.index_format);
01015         wined3d_device_set_base_vertex_index(device, stateblock->state.base_vertex_index);
01016     }
01017 
01018     if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration)
01019         wined3d_device_set_vertex_declaration(device, stateblock->state.vertex_declaration);
01020 
01021     if (stateblock->changed.material)
01022         wined3d_device_set_material(device, &stateblock->state.material);
01023 
01024     if (stateblock->changed.viewport)
01025         wined3d_device_set_viewport(device, &stateblock->state.viewport);
01026 
01027     if (stateblock->changed.scissorRect)
01028         wined3d_device_set_scissor_rect(device, &stateblock->state.scissor_rect);
01029 
01030     map = stateblock->changed.streamSource;
01031     for (i = 0; map; map >>= 1, ++i)
01032     {
01033         if (map & 1)
01034             wined3d_device_set_stream_source(device, i,
01035                     stateblock->state.streams[i].buffer,
01036                     0, stateblock->state.streams[i].stride);
01037     }
01038 
01039     map = stateblock->changed.streamFreq;
01040     for (i = 0; map; map >>= 1, ++i)
01041     {
01042         if (map & 1)
01043             wined3d_device_set_stream_source_freq(device, i,
01044                     stateblock->state.streams[i].frequency | stateblock->state.streams[i].flags);
01045     }
01046 
01047     map = stateblock->changed.textures;
01048     for (i = 0; map; map >>= 1, ++i)
01049     {
01050         DWORD stage;
01051 
01052         if (!(map & 1)) continue;
01053 
01054         stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS;
01055         wined3d_device_set_texture(device, stage, stateblock->state.textures[i]);
01056     }
01057 
01058     map = stateblock->changed.clipplane;
01059     for (i = 0; map; map >>= 1, ++i)
01060     {
01061         float clip[4];
01062 
01063         if (!(map & 1)) continue;
01064 
01065         clip[0] = (float) stateblock->state.clip_planes[i][0];
01066         clip[1] = (float) stateblock->state.clip_planes[i][1];
01067         clip[2] = (float) stateblock->state.clip_planes[i][2];
01068         clip[3] = (float) stateblock->state.clip_planes[i][3];
01069         wined3d_device_set_clip_plane(device, i, clip);
01070     }
01071 
01072     stateblock->device->stateBlock->state.lowest_disabled_stage = MAX_TEXTURES - 1;
01073     for (i = 0; i < MAX_TEXTURES - 1; ++i)
01074     {
01075         if (stateblock->device->stateBlock->state.texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
01076         {
01077             stateblock->device->stateBlock->state.lowest_disabled_stage = i;
01078             break;
01079         }
01080     }
01081 
01082     TRACE("Applied stateblock %p.\n", stateblock);
01083 
01084     return WINED3D_OK;
01085 }
01086 
01087 void stateblock_init_default_state(struct wined3d_stateblock *stateblock)
01088 {
01089     struct wined3d_device *device = stateblock->device;
01090     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
01091     struct wined3d_state *state = &stateblock->state;
01092     union
01093     {
01094         struct wined3d_line_pattern lp;
01095         DWORD d;
01096     } lp;
01097     union {
01098         float f;
01099         DWORD d;
01100     } tmpfloat;
01101     unsigned int i;
01102     struct wined3d_swapchain *swapchain;
01103     struct wined3d_surface *backbuffer;
01104     HRESULT hr;
01105 
01106     TRACE("stateblock %p.\n", stateblock);
01107 
01108     stateblock->blockType = WINED3D_SBT_INIT;
01109 
01110     memset(stateblock->changed.pixelShaderConstantsF, 0, device->d3d_pshader_constantF * sizeof(BOOL));
01111     memset(stateblock->changed.vertexShaderConstantsF, 0, device->d3d_vshader_constantF * sizeof(BOOL));
01112 
01113     /* Set some of the defaults for lights, transforms etc */
01114     memcpy(&state->transforms[WINED3D_TS_PROJECTION], identity, sizeof(identity));
01115     memcpy(&state->transforms[WINED3D_TS_VIEW], identity, sizeof(identity));
01116     for (i = 0; i < 256; ++i)
01117     {
01118         memcpy(&state->transforms[WINED3D_TS_WORLD_MATRIX(i)], identity, sizeof(identity));
01119     }
01120 
01121     state->fb = &device->fb;
01122 
01123     TRACE("Render states\n");
01124     /* Render states: */
01125     if (device->auto_depth_stencil)
01126        state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_TRUE;
01127     else
01128        state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_FALSE;
01129     state->render_states[WINED3D_RS_FILLMODE] = WINED3D_FILL_SOLID;
01130     state->render_states[WINED3D_RS_SHADEMODE] = WINED3D_SHADE_GOURAUD;
01131     lp.lp.repeat_factor = 0;
01132     lp.lp.line_pattern = 0;
01133     state->render_states[WINED3D_RS_LINEPATTERN] = lp.d;
01134     state->render_states[WINED3D_RS_ZWRITEENABLE] = TRUE;
01135     state->render_states[WINED3D_RS_ALPHATESTENABLE] = FALSE;
01136     state->render_states[WINED3D_RS_LASTPIXEL] = TRUE;
01137     state->render_states[WINED3D_RS_SRCBLEND] = WINED3D_BLEND_ONE;
01138     state->render_states[WINED3D_RS_DESTBLEND] = WINED3D_BLEND_ZERO;
01139     state->render_states[WINED3D_RS_CULLMODE] = WINED3D_CULL_CCW;
01140     state->render_states[WINED3D_RS_ZFUNC] = WINED3D_CMP_LESSEQUAL;
01141     state->render_states[WINED3D_RS_ALPHAFUNC] = WINED3D_CMP_ALWAYS;
01142     state->render_states[WINED3D_RS_ALPHAREF] = 0;
01143     state->render_states[WINED3D_RS_DITHERENABLE] = FALSE;
01144     state->render_states[WINED3D_RS_ALPHABLENDENABLE] = FALSE;
01145     state->render_states[WINED3D_RS_FOGENABLE] = FALSE;
01146     state->render_states[WINED3D_RS_SPECULARENABLE] = FALSE;
01147     state->render_states[WINED3D_RS_ZVISIBLE] = 0;
01148     state->render_states[WINED3D_RS_FOGCOLOR] = 0;
01149     state->render_states[WINED3D_RS_FOGTABLEMODE] = WINED3D_FOG_NONE;
01150     tmpfloat.f = 0.0f;
01151     state->render_states[WINED3D_RS_FOGSTART] = tmpfloat.d;
01152     tmpfloat.f = 1.0f;
01153     state->render_states[WINED3D_RS_FOGEND] = tmpfloat.d;
01154     tmpfloat.f = 1.0f;
01155     state->render_states[WINED3D_RS_FOGDENSITY] = tmpfloat.d;
01156     state->render_states[WINED3D_RS_EDGEANTIALIAS] = FALSE;
01157     state->render_states[WINED3D_RS_RANGEFOGENABLE] = FALSE;
01158     state->render_states[WINED3D_RS_STENCILENABLE] = FALSE;
01159     state->render_states[WINED3D_RS_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP;
01160     state->render_states[WINED3D_RS_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
01161     state->render_states[WINED3D_RS_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
01162     state->render_states[WINED3D_RS_STENCILREF] = 0;
01163     state->render_states[WINED3D_RS_STENCILMASK] = 0xffffffff;
01164     state->render_states[WINED3D_RS_STENCILFUNC] = WINED3D_CMP_ALWAYS;
01165     state->render_states[WINED3D_RS_STENCILWRITEMASK] = 0xffffffff;
01166     state->render_states[WINED3D_RS_TEXTUREFACTOR] = 0xffffffff;
01167     state->render_states[WINED3D_RS_WRAP0] = 0;
01168     state->render_states[WINED3D_RS_WRAP1] = 0;
01169     state->render_states[WINED3D_RS_WRAP2] = 0;
01170     state->render_states[WINED3D_RS_WRAP3] = 0;
01171     state->render_states[WINED3D_RS_WRAP4] = 0;
01172     state->render_states[WINED3D_RS_WRAP5] = 0;
01173     state->render_states[WINED3D_RS_WRAP6] = 0;
01174     state->render_states[WINED3D_RS_WRAP7] = 0;
01175     state->render_states[WINED3D_RS_CLIPPING] = TRUE;
01176     state->render_states[WINED3D_RS_LIGHTING] = TRUE;
01177     state->render_states[WINED3D_RS_AMBIENT] = 0;
01178     state->render_states[WINED3D_RS_FOGVERTEXMODE] = WINED3D_FOG_NONE;
01179     state->render_states[WINED3D_RS_COLORVERTEX] = TRUE;
01180     state->render_states[WINED3D_RS_LOCALVIEWER] = TRUE;
01181     state->render_states[WINED3D_RS_NORMALIZENORMALS] = FALSE;
01182     state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] = WINED3D_MCS_COLOR1;
01183     state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] = WINED3D_MCS_COLOR2;
01184     state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] = WINED3D_MCS_MATERIAL;
01185     state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] = WINED3D_MCS_MATERIAL;
01186     state->render_states[WINED3D_RS_VERTEXBLEND] = WINED3D_VBF_DISABLE;
01187     state->render_states[WINED3D_RS_CLIPPLANEENABLE] = 0;
01188     state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING] = FALSE;
01189     tmpfloat.f = 1.0f;
01190     state->render_states[WINED3D_RS_POINTSIZE] = tmpfloat.d;
01191     tmpfloat.f = 1.0f;
01192     state->render_states[WINED3D_RS_POINTSIZE_MIN] = tmpfloat.d;
01193     state->render_states[WINED3D_RS_POINTSPRITEENABLE] = FALSE;
01194     state->render_states[WINED3D_RS_POINTSCALEENABLE] = FALSE;
01195     tmpfloat.f = 1.0f;
01196     state->render_states[WINED3D_RS_POINTSCALE_A] = tmpfloat.d;
01197     tmpfloat.f = 0.0f;
01198     state->render_states[WINED3D_RS_POINTSCALE_B] = tmpfloat.d;
01199     tmpfloat.f = 0.0f;
01200     state->render_states[WINED3D_RS_POINTSCALE_C] = tmpfloat.d;
01201     state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS] = TRUE;
01202     state->render_states[WINED3D_RS_MULTISAMPLEMASK] = 0xffffffff;
01203     state->render_states[WINED3D_RS_PATCHEDGESTYLE] = WINED3D_PATCH_EDGE_DISCRETE;
01204     tmpfloat.f = 1.0f;
01205     state->render_states[WINED3D_RS_PATCHSEGMENTS] = tmpfloat.d;
01206     state->render_states[WINED3D_RS_DEBUGMONITORTOKEN] = 0xbaadcafe;
01207     tmpfloat.f = gl_info->limits.pointsize_max;
01208     state->render_states[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d;
01209     state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE;
01210     state->render_states[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f;
01211     tmpfloat.f = 0.0f;
01212     state->render_states[WINED3D_RS_TWEENFACTOR] = tmpfloat.d;
01213     state->render_states[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD;
01214     state->render_states[WINED3D_RS_POSITIONDEGREE] = WINED3D_DEGREE_CUBIC;
01215     state->render_states[WINED3D_RS_NORMALDEGREE] = WINED3D_DEGREE_LINEAR;
01216     /* states new in d3d9 */
01217     state->render_states[WINED3D_RS_SCISSORTESTENABLE] = FALSE;
01218     state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] = 0;
01219     tmpfloat.f = 1.0f;
01220     state->render_states[WINED3D_RS_MINTESSELLATIONLEVEL] = tmpfloat.d;
01221     state->render_states[WINED3D_RS_MAXTESSELLATIONLEVEL] = tmpfloat.d;
01222     state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE] = FALSE;
01223     tmpfloat.f = 0.0f;
01224     state->render_states[WINED3D_RS_ADAPTIVETESS_X] = tmpfloat.d;
01225     state->render_states[WINED3D_RS_ADAPTIVETESS_Y] = tmpfloat.d;
01226     tmpfloat.f = 1.0f;
01227     state->render_states[WINED3D_RS_ADAPTIVETESS_Z] = tmpfloat.d;
01228     tmpfloat.f = 0.0f;
01229     state->render_states[WINED3D_RS_ADAPTIVETESS_W] = tmpfloat.d;
01230     state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION] = FALSE;
01231     state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE] = FALSE;
01232     state->render_states[WINED3D_RS_CCW_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP;
01233     state->render_states[WINED3D_RS_CCW_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
01234     state->render_states[WINED3D_RS_CCW_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
01235     state->render_states[WINED3D_RS_CCW_STENCILFUNC] = WINED3D_CMP_ALWAYS;
01236     state->render_states[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f;
01237     state->render_states[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f;
01238     state->render_states[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f;
01239     state->render_states[WINED3D_RS_BLENDFACTOR] = 0xFFFFFFFF;
01240     state->render_states[WINED3D_RS_SRGBWRITEENABLE] = 0;
01241     state->render_states[WINED3D_RS_DEPTHBIAS] = 0;
01242     state->render_states[WINED3D_RS_WRAP8] = 0;
01243     state->render_states[WINED3D_RS_WRAP9] = 0;
01244     state->render_states[WINED3D_RS_WRAP10] = 0;
01245     state->render_states[WINED3D_RS_WRAP11] = 0;
01246     state->render_states[WINED3D_RS_WRAP12] = 0;
01247     state->render_states[WINED3D_RS_WRAP13] = 0;
01248     state->render_states[WINED3D_RS_WRAP14] = 0;
01249     state->render_states[WINED3D_RS_WRAP15] = 0;
01250     state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE] = FALSE;
01251     state->render_states[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE;
01252     state->render_states[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO;
01253     state->render_states[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD;
01254 
01255     /* Texture Stage States - Put directly into state block, we will call function below */
01256     for (i = 0; i < MAX_TEXTURES; ++i)
01257     {
01258         TRACE("Setting up default texture states for texture Stage %u.\n", i);
01259         memcpy(&state->transforms[WINED3D_TS_TEXTURE0 + i], identity, sizeof(identity));
01260         state->texture_states[i][WINED3D_TSS_COLOR_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_MODULATE;
01261         state->texture_states[i][WINED3D_TSS_COLOR_ARG1] = WINED3DTA_TEXTURE;
01262         state->texture_states[i][WINED3D_TSS_COLOR_ARG2] = WINED3DTA_CURRENT;
01263         state->texture_states[i][WINED3D_TSS_ALPHA_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_SELECT_ARG1;
01264         state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] = WINED3DTA_TEXTURE;
01265         state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] = WINED3DTA_CURRENT;
01266         state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00] = 0;
01267         state->texture_states[i][WINED3D_TSS_BUMPENV_MAT01] = 0;
01268         state->texture_states[i][WINED3D_TSS_BUMPENV_MAT10] = 0;
01269         state->texture_states[i][WINED3D_TSS_BUMPENV_MAT11] = 0;
01270         state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] = i;
01271         state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE] = 0;
01272         state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET] = 0;
01273         state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS] = WINED3D_TTFF_DISABLE;
01274         state->texture_states[i][WINED3D_TSS_COLOR_ARG0] = WINED3DTA_CURRENT;
01275         state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] = WINED3DTA_CURRENT;
01276         state->texture_states[i][WINED3D_TSS_RESULT_ARG] = WINED3DTA_CURRENT;
01277     }
01278     state->lowest_disabled_stage = 1;
01279 
01280         /* Sampler states*/
01281     for (i = 0 ; i <  MAX_COMBINED_SAMPLERS; ++i)
01282     {
01283         TRACE("Setting up default samplers states for sampler %u.\n", i);
01284         state->sampler_states[i][WINED3D_SAMP_ADDRESS_U] = WINED3D_TADDRESS_WRAP;
01285         state->sampler_states[i][WINED3D_SAMP_ADDRESS_V] = WINED3D_TADDRESS_WRAP;
01286         state->sampler_states[i][WINED3D_SAMP_ADDRESS_W] = WINED3D_TADDRESS_WRAP;
01287         state->sampler_states[i][WINED3D_SAMP_BORDER_COLOR] = 0;
01288         state->sampler_states[i][WINED3D_SAMP_MAG_FILTER] = WINED3D_TEXF_POINT;
01289         state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] = WINED3D_TEXF_POINT;
01290         state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] = WINED3D_TEXF_NONE;
01291         state->sampler_states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] = 0;
01292         state->sampler_states[i][WINED3D_SAMP_MAX_MIP_LEVEL] = 0;
01293         state->sampler_states[i][WINED3D_SAMP_MAX_ANISOTROPY] = 1;
01294         state->sampler_states[i][WINED3D_SAMP_SRGB_TEXTURE] = 0;
01295         /* TODO: Indicates which element of a multielement texture to use. */
01296         state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0;
01297         /* TODO: Vertex offset in the presampled displacement map. */
01298         state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0;
01299     }
01300 
01301     for (i = 0; i < gl_info->limits.textures; ++i)
01302     {
01303         state->textures[i] = NULL;
01304     }
01305 
01306     /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
01307     hr = wined3d_device_get_swapchain(device, 0, &swapchain);
01308     if (SUCCEEDED(hr) && swapchain)
01309     {
01310         hr = wined3d_swapchain_get_back_buffer(swapchain, 0, WINED3D_BACKBUFFER_TYPE_MONO, &backbuffer);
01311         if (SUCCEEDED(hr) && backbuffer)
01312         {
01313             struct wined3d_resource_desc desc;
01314 
01315             wined3d_resource_get_desc(&backbuffer->resource, &desc);
01316             wined3d_surface_decref(backbuffer);
01317 
01318             /* Set the default scissor rect values */
01319             state->scissor_rect.left = 0;
01320             state->scissor_rect.right = desc.width;
01321             state->scissor_rect.top = 0;
01322             state->scissor_rect.bottom = desc.height;
01323         }
01324 
01325         /* Set the default viewport */
01326         state->viewport.x = 0;
01327         state->viewport.y = 0;
01328         state->viewport.width = swapchain->desc.backbuffer_width;
01329         state->viewport.height = swapchain->desc.backbuffer_height;
01330         state->viewport.min_z = 0.0f;
01331         state->viewport.max_z = 1.0f;
01332 
01333         wined3d_swapchain_decref(swapchain);
01334     }
01335 
01336     TRACE("Done.\n");
01337 }
01338 
01339 static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
01340         struct wined3d_device *device, enum wined3d_stateblock_type type)
01341 {
01342     unsigned int i;
01343     HRESULT hr;
01344 
01345     stateblock->ref = 1;
01346     stateblock->device = device;
01347     stateblock->blockType = type;
01348 
01349     for (i = 0; i < LIGHTMAP_SIZE; i++)
01350     {
01351         list_init(&stateblock->state.light_map[i]);
01352     }
01353 
01354     hr = stateblock_allocate_shader_constants(stateblock);
01355     if (FAILED(hr)) return hr;
01356 
01357     /* The WINED3D_SBT_INIT stateblock type is used during initialization to
01358      * produce a placeholder stateblock so other functions called can update a
01359      * state block. */
01360     if (type == WINED3D_SBT_INIT || type == WINED3D_SBT_RECORDED) return WINED3D_OK;
01361 
01362     TRACE("Updating changed flags appropriate for type %#x.\n", type);
01363 
01364     switch (type)
01365     {
01366         case WINED3D_SBT_ALL:
01367             stateblock_init_lights(stateblock, device->stateBlock->state.light_map);
01368             stateblock_savedstates_set_all(&stateblock->changed, device->d3d_vshader_constantF,
01369                                            device->d3d_pshader_constantF);
01370             break;
01371 
01372         case WINED3D_SBT_PIXEL_STATE:
01373             stateblock_savedstates_set_pixel(&stateblock->changed, device->d3d_pshader_constantF);
01374             break;
01375 
01376         case WINED3D_SBT_VERTEX_STATE:
01377             stateblock_init_lights(stateblock, device->stateBlock->state.light_map);
01378             stateblock_savedstates_set_vertex(&stateblock->changed, device->d3d_vshader_constantF);
01379             break;
01380 
01381         default:
01382             FIXME("Unrecognized state block type %#x.\n", type);
01383             break;
01384     }
01385 
01386     stateblock_init_contained_states(stateblock);
01387     wined3d_stateblock_capture(stateblock);
01388 
01389     return WINED3D_OK;
01390 }
01391 
01392 HRESULT CDECL wined3d_stateblock_create(struct wined3d_device *device,
01393         enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock)
01394 {
01395     struct wined3d_stateblock *object;
01396     HRESULT hr;
01397 
01398     TRACE("device %p, type %#x, stateblock %p.\n",
01399             device, type, stateblock);
01400 
01401     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
01402     if (!object)
01403     {
01404         ERR("Failed to allocate stateblock memory.\n");
01405         return E_OUTOFMEMORY;
01406     }
01407 
01408     hr = stateblock_init(object, device, type);
01409     if (FAILED(hr))
01410     {
01411         WARN("Failed to initialize stateblock, hr %#x.\n", hr);
01412         HeapFree(GetProcessHeap(), 0, object);
01413         return hr;
01414     }
01415 
01416     TRACE("Created stateblock %p.\n", object);
01417     *stateblock = object;
01418 
01419     return WINED3D_OK;
01420 }

Generated on Sat May 26 2012 04:20:41 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.