glsl_shader.c revision 5387f218510e99d18a86d9971e39f526ada790c4
1N/A#include "wined3d_private.h"
1N/Aenum heap_node_op
1N/Astruct constant_entry
1N/Astruct constant_heap
1N/Astruct shader_glsl_priv {
1N/Astruct glsl_shader_prog_link {
1N/A#define WINEFIXUPINFO_GET(_p) get_fixup_info((const IWineD3DPixelShaderImpl*)(_p)->pshader, (_p)->inp2Fixup_info)
1N/Astruct shader_glsl_ctx_priv {
1N/Astruct glsl_ps_compiled_shader
struct glsl_pshader_private
struct glsl_vs_compiled_shader
struct glsl_vshader_private
switch (type)
#define WINED3D_TO_STR(u) case u: return #u
if (!cbStr)
return NULL;
p = *ptr;
*pcbStr = 0;
return NULL;
*pcbStr = 0;
int infologLength = 0;
char *infoLog;
static const char * const spam[] =
#ifndef VBOXWINEDBG_SHADERS
&infologLength));
int cbPtr;
if (is_spam)
static void shader_glsl_dump_shader_source(const struct wined3d_gl_info *gl_info, GLhandleARB shader)
char *ptr;
int cbPtr;
if (!source)
static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program)
WDLOG(("\n***************************dumping program %d******************************\n", program));
if (!objects)
for (i = 0; i < object_count; ++i)
WDLOG(("\n***************************END dumping program %d******************************\n\n", program));
static void shader_glsl_validate_compile_link(const struct wined3d_gl_info *gl_info, GLhandleARB program, GLboolean fIsProgram)
#ifndef VBOXWINEDBG_SHADERS
if (!fIsProgram)
if (!tmp)
#ifndef VBOXWINEDBG_SHADERS
#ifdef VBOXWINEDBG_SHADERS
if (fIsProgram)
if (!tmp)
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const float *constants,
const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
int stack_idx = 0;
unsigned int idx;
if (constant_locations[idx] != -1) GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
while (stack_idx >= 0)
case HEAP_NODE_TRAVERSE_LEFT:
case HEAP_NODE_TRAVERSE_RIGHT:
case HEAP_NODE_POP:
--stack_idx;
static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info, GLint location, const GLfloat *data)
static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info, const float *constants,
const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
int stack_idx = 0;
unsigned int idx;
while (stack_idx >= 0)
case HEAP_NODE_TRAVERSE_LEFT:
case HEAP_NODE_TRAVERSE_RIGHT:
case HEAP_NODE_POP:
--stack_idx;
static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
while (ptr) {
static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
const char *prefix;
while (ptr) {
WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry)->constant_version = 0;
static const struct ps_np2fixup_info * get_fixup_info(const IWineD3DPixelShaderImpl *shader, UINT inp2fixup_info)
return NULL;
return NULL;
return NULL;
static void shader_glsl_load_np2fixup_constants(
char usePixelShader,
char useVertexShader) {
const struct glsl_shader_prog_link* prog = ((struct shader_glsl_priv *)(deviceImpl->shader_priv))->glsl_program;
if (!prog) {
if (!usePixelShader) {
UINT i;
const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
if (!tex) {
GL_EXTCALL(glUniform4fvARB(prog->np2Fixup_location, np2Fixup_info->num_consts, np2fixup_constants));
if (!prog) {
if (useVertexShader) {
shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations, stateBlock->vertexShaderConstantI,
if (usePixelShader) {
shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations, stateBlock->pixelShaderConstantI,
/* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
for(i = 0; i < MAX_TEXTURES; i++) {
const float *data;
unsigned int parent_idx;
static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
UINT i;
UINT i;
return ret;
unsigned int i, extra_constants_needed = 0;
unsigned max_constantsF;
/* Unless the shader uses indirect addressing, always declare the maximum array size and ignore that we need some
* uniforms privately. E.g. if GL supports 256 uniforms, and we need 2 for the pos fixup and immediate values, still
* declare VC[256]. If the shader needs more uniforms than we have it won't work in any case. If it uses less, the
* compiler will figure out which uniforms are really used and strip them out. This allows a shader to use c255 on
* If the shader uses indirect addressing the compiler must assume that all declared uniforms are used. In this case,
* 2) The shader uses indirect addressing, less constants than supported, but uses a constant index > #supported consts
if (pshader)
/* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix).
* Subtract another uniform for immediate values, which have to be loaded via uniform by the driver as well.
* The shader code only uses 0.5, 2.0, 1.0, 128 and -128 in vertex shader code, so one vec4 should be enough
#ifdef VBOX_WITH_WDDM
/* tmp work-around to make Internet Explorer in win8 work with GPU supporting only with 256 shader uniform vars
/* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly,
* so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but
/* Set by driver quirks in directx.c */
/* Always declare the full set of constants, the compiler can remove the unused ones because d3d doesn't(yet)
* support indirect int and bool constant addressing. This avoids problems if the app uses e.g. i0 and i9.
if(!pshader) {
srgb_cmp);
context->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height,
case WINED3DSTT_1D:
case WINED3DSTT_2D:
IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) == GL_TEXTURE_RECTANGLE_ARB) {
case WINED3DSTT_CUBE:
case WINED3DSTT_VOLUME:
shader_addline(buffer, "varying vec4 IN[%u];\n", vec4_varyings(reg_maps->shader_version.major, gl_info));
shader_addline(buffer, "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n");
* For more information, see http://wiki.winehq.org/DirectX-Shaders
static const char * const shift_glsl_tab[] = {
/* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
static void shader_glsl_gen_modifier(DWORD src_modifier, const char *in_reg, const char *in_regswizzle, char *out_str)
out_str[0] = 0;
switch (src_modifier)
case WINED3DSPSM_DW:
case WINED3DSPSM_NONE:
case WINED3DSPSM_NEG:
case WINED3DSPSM_NOT:
case WINED3DSPSM_BIAS:
case WINED3DSPSM_BIASNEG:
case WINED3DSPSM_SIGN:
case WINED3DSPSM_SIGNNEG:
case WINED3DSPSM_COMP:
case WINED3DSPSM_X2:
case WINED3DSPSM_X2NEG:
case WINED3DSPSM_ABS:
case WINED3DSPSM_ABSNEG:
static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
case WINED3DSPR_TEMP:
case WINED3DSPR_INPUT:
if (!pshader)
if (idx)
case WINED3DSPR_CONST:
case WINED3DSPR_CONSTINT:
case WINED3DSPR_CONSTBOOL:
case WINED3DSPR_LOOP:
case WINED3DSPR_SAMPLER:
case WINED3DSPR_COLOROUT:
case WINED3DSPR_RASTOUT:
case WINED3DSPR_DEPTHOUT:
case WINED3DSPR_ATTROUT:
case WINED3DSPR_TEXCRDOUT:
if (This->baseShader.reg_maps.shader_version.major >= 3) sprintf(register_name, "OUT[%u]", reg->idx);
case WINED3DSPR_MISCTYPE:
case WINED3DSPR_IMMCONST:
case WINED3D_IMMCONST_FLOAT:
case WINED3D_IMMCONST_FLOAT4:
static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *param, char *write_mask)
return mask;
unsigned int size = 0;
return size;
shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, glsl_src->param_str);
if (mask) shader_addline(buffer, "%s%s = %s(", glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
return mask;
static DWORD shader_glsl_append_dst(struct wined3d_shader_buffer *buffer, const struct wined3d_shader_instruction *ins)
if (!modifiers) return;
switch (op) {
switch(sampler_type) {
case WINED3DSTT_1D:
if(lod) {
else if (grad)
case WINED3DSTT_2D:
if(texrect) {
if(lod) {
else if (grad)
if(lod) {
else if (grad)
case WINED3DSTT_CUBE:
if(lod) {
else if (grad)
sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
case WINED3DSTT_VOLUME:
if(lod) {
else if (grad)
sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
switch(channel_source)
case CHANNEL_SOURCE_ZERO:
case CHANNEL_SOURCE_ONE:
case CHANNEL_SOURCE_X:
case CHANNEL_SOURCE_Y:
case CHANNEL_SOURCE_Z:
case CHANNEL_SOURCE_W:
static void shader_glsl_color_correction(const struct wined3d_shader_instruction *ins, struct color_fixup_desc fixup)
mask = 0;
shader_addline(ins->ctx->buffer, "%s%s = %s;\n", dst_param.reg_name, dst_param.mask_str, arguments);
static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
const char *sampler_base;
if(bias) {
DebugBreak();
if (tmirror_tmp_reg)
if(bias) {
if (np2_fixup) {
char op;
unsigned int dst_size = 0;
shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
shader_addline(ins->ctx->buffer, "cross(%s, %s)%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
unsigned int dst_size;
shader_addline(buffer, "vec%d(pow(abs(%s), %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
unsigned int dst_size;
const char *instruction;
unsigned int mask_size;
shader_addline(ins->ctx->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str);
unsigned int mask_size;
unsigned int mask_size;
unsigned int mask_size;
unsigned int mask_size;
const char *compare;
case WINED3DSIH_SLT:
case WINED3DSIH_SGE:
write_mask = 0;
if (!write_mask) continue;
if (!write_mask) continue;
if(temp_destination) {
write_mask = 0;
if (!write_mask) continue;
int nComponents = 0;
case WINED3DSIH_M4x4:
case WINED3DSIH_M4x3:
case WINED3DSIH_M3x4:
case WINED3DSIH_M3x3:
case WINED3DSIH_M3x2:
for (i = 0; i < nComponents; ++i)
* step(0.0, x) will return 1 if src.x > 0.0, and 0 otherwise. So if y is 0 we get pow(0.0 * 1.0, power),
src0y_param.param_str, src1y_param.param_str, src0z_param.param_str, src1w_param.param_str, dst_mask);
* VS 2.0 requires that specific cosine and sine constants be passed to this instruction so the hardware
* can handle it. But, these functions are built-in for GLSL, so we can just ignore the last 2 params.
switch (write_mask) {
case WINED3DSP_WRITEMASK_0:
case WINED3DSP_WRITEMASK_1:
shader_addline(ins->ctx->buffer, "vec2(cos(%s), sin(%s)));\n", src0_param.param_str, src0_param.param_str);
/* Try to hardcode the loop control parameters if possible. Direct3D 9 class hardware doesn't support real
* varying indexing, but Microsoft designed this feature for Shader model 2.x+. If the loop control is
* known at compile time, the GLSL compiler can unroll the loop, and replace indirect addressing with direct
if (control_values)
if(control_values) {
shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, ins->src[0].reg.idx);
/* No-op. The closing } is written when a new function is started, and at the end of the shader. This
DWORD flags = (priv->cur_ps_args->tex_transform >> (sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT))
case WINED3DTTFF_COUNT4:
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, NULL,
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str,
if (!(ins->ctx->reg_maps->shader_version.major == 1 && ins->ctx->reg_maps->shader_version.minor == 4))
shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
switch(mask_size)
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
unsigned int mask_size;
shader_addline(ins->ctx->buffer, "vec%d(dot(T%u.xyz, %s)));\n", mask_size, dstreg, src0_param.param_str);
* this doesn't always work, so clamp the results manually. Whether or not the x value is clamped at 1
* too is irrelevant, since if x = 0, any y value < 1.0 (and > 1.0 is not allowed) results in a result
shader_addline(ins->ctx->buffer, "gl_FragDepth = (tmp0.y == 0.0) ? 1.0 : clamp(tmp0.x / tmp0.y, 0.0, 1.0);\n");
shader_addline(buffer, "tmp0.%c = dot(T%u.xyz, %s);\n", 'x' + current_state->current_row, reg, src0_param.param_str);
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
* Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
shader_addline(ins->ctx->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
shader_addline(buffer, "tmp1.xyz = normalize(vec3(gl_TexCoord[%u].w, gl_TexCoord[%u].w, gl_TexCoord[%u].w));\n",
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
case WINED3DTTFF_COUNT4:
shader_addline(ins->ctx->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
unsigned int mask_size;
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
static void shader_glsl_input_pack(IWineD3DPixelShader *iface, struct wined3d_shader_buffer *buffer,
const struct wined3d_shader_signature_element *input_signature, const struct shader_reg_maps *reg_maps,
const char *semantic_name;
if (semantic_idx == 0)
static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_shader_prog_link *entry) {
return entry ? WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry) : NULL;
static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info,
WARN("Attempting to delete program %u created in ctx %p from ctx %p\n", entry->programId, entry->context, context_get_current());
static void handle_ps3_input(struct wined3d_shader_buffer *buffer, const struct wined3d_gl_info *gl_info, const DWORD *map,
const struct wined3d_shader_signature_element *input_signature, const struct shader_reg_maps *reg_maps_in,
const struct wined3d_shader_signature_element *output_signature, const struct shader_reg_maps *reg_maps_out)
if (!output_signature)
else if (map[i] == ~0U)
if (!output_signature)
if (semantic_idx_in == 0)
if(!found) {
unsigned int size = 0;
size++;
size++;
size++;
size++;
if (i == in_count) {
static void generate_texcoord_assignment(struct wined3d_shader_buffer *buffer, IWineD3DVertexShaderImpl *vs, IWineD3DPixelShaderImpl *ps)
for (i = 0, map = ps->baseShader.reg_maps.texcoord; map && i < min(8, MAX_REG_TEXCRD); map >>= 1, ++i)
/* so far we assume that if texcoord_mask has any write flags, they are assigned appropriately with pixel shader */
IWineD3DVertexShader *vertexshader, IWineD3DPixelShader *pixelshader, const struct wined3d_gl_info *gl_info)
const char *semantic_name;
/* That one is easy: The vertex shader writes to the builtin varyings, the pixel shader reads from them.
if (semantic_idx == 0)
return ret;
static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info,
const float *value;
shader_generate_glsl_declarations(context, buffer, (IWineD3DBaseShader *)This, reg_maps, &priv_ctx);
shader_addline(buffer, "bvec3 srgb_compare = lessThan(gl_FragData[0].xyz, vec3(srgb_const1.x));\n");
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
case FOG_OFF: break;
case FOG_LINEAR:
case FOG_EXP:
case FOG_EXP2:
shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);\n");
return shader_obj;
shader_generate_glsl_declarations(context, buffer, (IWineD3DBaseShader *)This, reg_maps, &priv_ctx);
/* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
return shader_obj;
UINT i;
shader->baseShader.backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
*inp2fixup_info = i;
if(!new_array) {
memset(&shader_data->gl_shaders[shader_data->num_gl_shaders].np2fixup, 0, sizeof(struct ps_np2fixup_info));
return ret;
static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new,
UINT i;
shader->baseShader.backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
if(!new_array) {
return ret;
if (vshader) find_vs_compile_args((IWineD3DVertexShaderImpl *)vshader, device->stateBlock, &vs_compile_args);
if (pshader) find_ps_compile_args((IWineD3DPixelShaderImpl *)pshader, device->stateBlock, &ps_compile_args);
entry = get_glsl_program_entry(priv, vshader, pshader, &vs_compile_args, &ps_compile_args, context);
if (entry) {
if (vshader)
reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
list_add_head(&((IWineD3DBaseShaderImpl *)vshader)->baseShader.linked_programs, &entry->vshader_entry);
if (pshader)
list_add_head(&((IWineD3DBaseShaderImpl *)pshader)->baseShader.linked_programs, &entry->pshader_entry);
for (i = 0; i < MAX_CONST_I; ++i)
for (i = 0; i < MAX_CONST_I; ++i)
if(pshader) {
for(i = 0; i < MAX_TEXTURES; i++) {
if (pshader
#ifdef DEBUG_misha
static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type)
static const char *blt_vshader[] =
NULL,
NULL,
return program_id;
old_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;
current_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;
#ifdef DEBUG_misha
* constants. This has to be done because it can't be guaranteed that sampler() (from state.c) is
* called between selecting the shader and using it, which results in wrong fixup for some frames. */
if (!*blt_program) {
#ifdef DEBUG_misha
#ifdef DEBUG_misha
#ifdef DEBUG_misha
if(pshader) {
ENTER_GL();
LEAVE_GL();
ENTER_GL();
LEAVE_GL();
ENTER_GL();
if(pshader) {
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, vshader_entry) {
LEAVE_GL();
if(pshader) {
UINT i;
ENTER_GL();
LEAVE_GL();
UINT i;
ENTER_GL();
LEAVE_GL();
int cmp;
SIZE_T size = (constant_count + 1) * sizeof(*heap->entries) + constant_count * sizeof(*heap->positions);
if (!mem)
return FALSE;
return TRUE;
struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
return WINED3D_OK;
fail:
return E_OUTOFMEMORY;
ENTER_GL();
for (i = 0; i < tex_type_count; ++i)
LEAVE_GL();
return FALSE;
* of native instructions, so use that here. For more info see the pixel shader versioning code below.
TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (pCaps->VertexShaderVersion >> 8) & 0xff, pCaps->VertexShaderVersion & 0xff);
/* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
* NOTE: ps3.0 hardware requires 512 or more instructions but ati and nvidia offer 'enough' (1024 vs 4096) on their most basic ps3.0 hardware.
TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (pCaps->PixelShaderVersion >> 8) & 0xff, pCaps->PixelShaderVersion & 0xff);
return TRUE;
return FALSE;
if (!hw_fct)
#ifdef VBOXWINEDBG_SHADERS