mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
Compare commits
8 commits
a50dd3392b
...
2af94b3952
Author | SHA1 | Date | |
---|---|---|---|
|
2af94b3952 | ||
|
8b8ca1acc5 | ||
|
1fe2f01aac | ||
|
b38b973efb | ||
|
6a978ed054 | ||
|
1edafed827 | ||
|
aaac358bed | ||
|
d9de4b168c |
13 changed files with 720 additions and 221 deletions
|
@ -14,6 +14,7 @@ SOURCES = \
|
|||
device.c \
|
||||
directx.c \
|
||||
ffp_gl.c \
|
||||
ffp_hlsl.c \
|
||||
gl_compat.c \
|
||||
glsl_shader.c \
|
||||
palette.c \
|
||||
|
|
|
@ -4928,6 +4928,7 @@ static void wined3d_adapter_gl_init_d3d_info(struct wined3d_adapter_gl *adapter_
|
|||
d3d_info->feature_level = feature_level_from_caps(gl_info, &shader_caps, &d3d_info->ffp_fragment_caps);
|
||||
d3d_info->filling_convention_offset = gl_info->filling_convention_offset;
|
||||
d3d_info->persistent_map = !!gl_info->supported[ARB_BUFFER_STORAGE];
|
||||
d3d_info->ffp_hlsl = wined3d_settings.ffp_hlsl;
|
||||
|
||||
if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
|
||||
d3d_info->multisample_draw_location = WINED3D_LOCATION_TEXTURE_RGB;
|
||||
|
|
|
@ -2359,6 +2359,7 @@ static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_
|
|||
d3d_info->fences = true;
|
||||
d3d_info->persistent_map = true;
|
||||
d3d_info->gpu_push_constants = true;
|
||||
d3d_info->ffp_hlsl = true;
|
||||
|
||||
/* Like GL, Vulkan doesn't explicitly specify a filling convention and only mandates that a
|
||||
* shared edge of two adjacent triangles generate a fragment for exactly one of the triangles.
|
||||
|
|
|
@ -161,8 +161,8 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf
|
|||
const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info)
|
||||
{
|
||||
/* We need to deal with frequency data! */
|
||||
BOOL use_vshader = use_vs(state) || (d3d_info->ffp_hlsl && state->shader[WINED3D_SHADER_TYPE_VERTEX]);
|
||||
struct wined3d_vertex_declaration *declaration = state->vertex_declaration;
|
||||
BOOL use_vshader = use_vs(state);
|
||||
unsigned int i;
|
||||
|
||||
stream_info->use_map = 0;
|
||||
|
|
|
@ -2123,15 +2123,23 @@ static void wined3d_cs_exec_push_constants(struct wined3d_cs *cs, const void *da
|
|||
{
|
||||
const struct wined3d_cs_push_constants *op = data;
|
||||
struct wined3d_device *device = cs->c.device;
|
||||
unsigned int ffp_start_idx, ffp_end_idx;
|
||||
unsigned int context_count, i;
|
||||
|
||||
/* The constant buffers were already updated; this op is just to mark the
|
||||
* constants as invalid in the device state. */
|
||||
|
||||
ffp_start_idx = op->start_idx / sizeof(struct wined3d_vec4);
|
||||
ffp_end_idx = (op->start_idx + op->count + sizeof(struct wined3d_vec4)) / sizeof(struct wined3d_vec4);
|
||||
|
||||
if (op->type == WINED3D_PUSH_CONSTANTS_VS_F)
|
||||
device->shader_backend->shader_update_float_vertex_constants(device, op->start_idx, op->count);
|
||||
else if (op->type == WINED3D_PUSH_CONSTANTS_PS_F)
|
||||
device->shader_backend->shader_update_float_pixel_constants(device, op->start_idx, op->count);
|
||||
else if (op->type == WINED3D_PUSH_CONSTANTS_VS_FFP)
|
||||
device->shader_backend->shader_update_float_vertex_constants(device, ffp_start_idx, ffp_end_idx - ffp_start_idx);
|
||||
else if (op->type == WINED3D_PUSH_CONSTANTS_PS_FFP)
|
||||
device->shader_backend->shader_update_float_pixel_constants(device, ffp_start_idx, ffp_end_idx - ffp_start_idx);
|
||||
|
||||
for (i = 0, context_count = device->context_count; i < context_count; ++i)
|
||||
device->contexts[i]->constant_update_mask |= op->update_mask;
|
||||
|
|
|
@ -1667,6 +1667,22 @@ static void device_free_depth_stencil_state(struct wine_rb_entry *entry, void *c
|
|||
wined3d_depth_stencil_state_decref(state);
|
||||
}
|
||||
|
||||
static void device_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *context)
|
||||
{
|
||||
struct wined3d_ffp_vs *vs = WINE_RB_ENTRY_VALUE(entry, struct wined3d_ffp_vs, entry);
|
||||
|
||||
wined3d_shader_decref(vs->shader);
|
||||
free(vs);
|
||||
}
|
||||
|
||||
static void device_free_ffp_pixel_shader(struct wine_rb_entry *entry, void *context)
|
||||
{
|
||||
struct wined3d_ffp_ps *ps = WINE_RB_ENTRY_VALUE(entry, struct wined3d_ffp_ps, entry);
|
||||
|
||||
wined3d_shader_decref(ps->shader);
|
||||
free(ps);
|
||||
}
|
||||
|
||||
void wined3d_device_uninit_3d(struct wined3d_device *device)
|
||||
{
|
||||
struct wined3d_state *state = device->cs->c.state;
|
||||
|
@ -1714,6 +1730,8 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
|
|||
wine_rb_destroy(&device->rasterizer_states, device_free_rasterizer_state, NULL);
|
||||
wine_rb_destroy(&device->blend_states, device_free_blend_state, NULL);
|
||||
wine_rb_destroy(&device->depth_stencil_states, device_free_depth_stencil_state, NULL);
|
||||
wine_rb_destroy(&device->ffp_vertex_shaders, device_free_ffp_vertex_shader, NULL);
|
||||
wine_rb_destroy(&device->ffp_pixel_shaders, device_free_ffp_pixel_shader, NULL);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
|
||||
{
|
||||
|
@ -5515,6 +5533,8 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
|
|||
wine_rb_init(&device->rasterizer_states, wined3d_rasterizer_state_compare);
|
||||
wine_rb_init(&device->blend_states, wined3d_blend_state_compare);
|
||||
wine_rb_init(&device->depth_stencil_states, wined3d_depth_stencil_state_compare);
|
||||
wine_rb_init(&device->ffp_vertex_shaders, wined3d_ffp_vertex_program_key_compare);
|
||||
wine_rb_init(&device->ffp_pixel_shaders, wined3d_ffp_frag_program_key_compare);
|
||||
|
||||
if (vertex_pipeline->vp_states && fragment_pipeline->states
|
||||
&& FAILED(hr = compile_state_table(device->state_table, device->multistate_funcs,
|
||||
|
@ -5527,6 +5547,8 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
|
|||
wine_rb_destroy(&device->blend_states, NULL, NULL);
|
||||
wine_rb_destroy(&device->depth_stencil_states, NULL, NULL);
|
||||
wine_rb_destroy(&device->so_descs, NULL, NULL);
|
||||
wine_rb_destroy(&device->ffp_vertex_shaders, NULL, NULL);
|
||||
wine_rb_destroy(&device->ffp_pixel_shaders, NULL, NULL);
|
||||
wined3d_decref(device->wined3d);
|
||||
return hr;
|
||||
}
|
||||
|
@ -5554,6 +5576,8 @@ err:
|
|||
wine_rb_destroy(&device->blend_states, NULL, NULL);
|
||||
wine_rb_destroy(&device->depth_stencil_states, NULL, NULL);
|
||||
wine_rb_destroy(&device->so_descs, NULL, NULL);
|
||||
wine_rb_destroy(&device->ffp_vertex_shaders, NULL, NULL);
|
||||
wine_rb_destroy(&device->ffp_pixel_shaders, NULL, NULL);
|
||||
wined3d_decref(device->wined3d);
|
||||
return hr;
|
||||
}
|
||||
|
|
246
dlls/wined3d/ffp_hlsl.c
Normal file
246
dlls/wined3d/ffp_hlsl.c
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Fixed-function pipeline replacement implemented using HLSL shaders
|
||||
*
|
||||
* Copyright 2006 Jason Green
|
||||
* Copyright 2006-2007 Henri Verbeet
|
||||
* Copyright 2007-2009,2013 Stefan Dösinger for CodeWeavers
|
||||
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
|
||||
* Copyright 2022,2024 Elizabeth Figura for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wined3d_private.h"
|
||||
#include <vkd3d_shader.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
||||
|
||||
static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings *settings,
|
||||
struct wined3d_string_buffer *buffer)
|
||||
{
|
||||
if (settings->lighting)
|
||||
FIXME("Ignoring lighting.\n");
|
||||
|
||||
if (settings->point_size)
|
||||
FIXME("Ignoring point size.\n");
|
||||
|
||||
if (settings->transformed)
|
||||
FIXME("Ignoring pretransformed vertices.\n");
|
||||
|
||||
if (settings->vertexblends)
|
||||
FIXME("Ignoring vertex blend.\n");
|
||||
|
||||
if (settings->normal)
|
||||
FIXME("Ignoring normals.\n");
|
||||
|
||||
if (settings->fog_mode != WINED3D_FFP_VS_FOG_OFF)
|
||||
FIXME("Ignoring fog.\n");
|
||||
|
||||
/* This must be kept in sync with struct wined3d_ffp_vs_constants. */
|
||||
shader_addline(buffer, "uniform struct\n");
|
||||
shader_addline(buffer, "{\n");
|
||||
shader_addline(buffer, " float4x4 modelview_matrices[%u];\n", MAX_VERTEX_BLENDS);
|
||||
shader_addline(buffer, " float4x4 projection_matrix;\n");
|
||||
shader_addline(buffer, " float4x4 texture_matrices[%u];\n", WINED3D_MAX_FFP_TEXTURES);
|
||||
shader_addline(buffer, " float4 point_params;\n");
|
||||
shader_addline(buffer, " struct\n");
|
||||
shader_addline(buffer, " {\n");
|
||||
shader_addline(buffer, " float4 diffuse;\n");
|
||||
shader_addline(buffer, " float4 ambient;\n");
|
||||
shader_addline(buffer, " float4 specular;\n");
|
||||
shader_addline(buffer, " float4 emissive;\n");
|
||||
shader_addline(buffer, " float power;\n");
|
||||
shader_addline(buffer, " } material;\n");
|
||||
shader_addline(buffer, " float4 ambient_colour;\n");
|
||||
shader_addline(buffer, " struct\n");
|
||||
shader_addline(buffer, " {\n");
|
||||
shader_addline(buffer, " float4 diffuse, specular, ambient;\n");
|
||||
shader_addline(buffer, " float4 position, direction;\n");
|
||||
shader_addline(buffer, " float4 packed_params;\n");
|
||||
shader_addline(buffer, " float4 attenuation;\n");
|
||||
shader_addline(buffer, " } lights[%u];\n", WINED3D_MAX_ACTIVE_LIGHTS);
|
||||
shader_addline(buffer, "} c;\n");
|
||||
|
||||
shader_addline(buffer, "struct input\n");
|
||||
shader_addline(buffer, "{\n");
|
||||
shader_addline(buffer, " float4 pos : POSITION;\n");
|
||||
shader_addline(buffer, " float4 blend_weight : BLENDWEIGHT;\n");
|
||||
shader_addline(buffer, " uint blend_indices : BLENDINDICES;\n");
|
||||
shader_addline(buffer, " float3 normal : NORMAL;\n");
|
||||
shader_addline(buffer, " float point_size : PSIZE;\n");
|
||||
shader_addline(buffer, " float4 diffuse : COLOR0;\n");
|
||||
shader_addline(buffer, " float4 specular : COLOR1;\n");
|
||||
shader_addline(buffer, " float4 texcoord[%u] : TEXCOORD;\n", WINED3D_MAX_FFP_TEXTURES);
|
||||
shader_addline(buffer, "};\n\n");
|
||||
|
||||
shader_addline(buffer, "struct output\n");
|
||||
shader_addline(buffer, "{\n");
|
||||
shader_addline(buffer, " float4 pos : POSITION;\n");
|
||||
shader_addline(buffer, " float4 diffuse : COLOR0;\n");
|
||||
shader_addline(buffer, " float4 specular : COLOR1;\n");
|
||||
for (unsigned int i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i)
|
||||
{
|
||||
if (((settings->texgen[i] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU) || (settings->texcoords & (1u << i)))
|
||||
shader_addline(buffer, " float4 texcoord%u : TEXCOORD%u;\n", i, i);
|
||||
}
|
||||
shader_addline(buffer, "};\n\n");
|
||||
|
||||
shader_addline(buffer, "void main(in struct input i, out struct output o)\n");
|
||||
shader_addline(buffer, "{\n");
|
||||
shader_addline(buffer, " float4 ec_pos = 0.0;\n\n");
|
||||
|
||||
shader_addline(buffer, " ec_pos += mul(c.modelview_matrices[0], float4(i.pos.xyz, 1.0));\n\n");
|
||||
|
||||
shader_addline(buffer, " o.pos = mul(c.projection_matrix, ec_pos);\n");
|
||||
shader_addline(buffer, " ec_pos /= ec_pos.w;\n\n");
|
||||
|
||||
/* No lighting. */
|
||||
if (settings->diffuse)
|
||||
shader_addline(buffer, " o.diffuse = i.diffuse;\n");
|
||||
else
|
||||
shader_addline(buffer, " o.diffuse = 1.0;\n");
|
||||
shader_addline(buffer, " o.specular = i.specular;\n\n");
|
||||
|
||||
for (unsigned int i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i)
|
||||
{
|
||||
switch (settings->texgen[i] & 0xffff0000)
|
||||
{
|
||||
case WINED3DTSS_TCI_PASSTHRU:
|
||||
if (settings->texcoords & (1u << i))
|
||||
shader_addline(buffer, " o.texcoord%u = mul(c.texture_matrices[%u], i.texcoord[%u]);\n",
|
||||
i, i, settings->texgen[i] & 0x0000ffff);
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled texgen %#x.\n", settings->texgen[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (settings->fog_mode)
|
||||
{
|
||||
case WINED3D_FFP_VS_FOG_OFF:
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled fog mode %#x.\n", settings->fog_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
shader_addline(buffer, "}\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ffp_hlsl_generate_pixel_shader(const struct ffp_frag_settings *settings,
|
||||
struct wined3d_string_buffer *string)
|
||||
{
|
||||
FIXME("Not yet implemented.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool compile_hlsl_shader(const struct wined3d_string_buffer *hlsl,
|
||||
struct vkd3d_shader_code *sm1, const char *profile)
|
||||
{
|
||||
struct vkd3d_shader_hlsl_source_info hlsl_source_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
|
||||
struct vkd3d_shader_compile_info compile_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
|
||||
char *messages;
|
||||
int ret;
|
||||
|
||||
compile_info.source.code = hlsl->buffer;
|
||||
compile_info.source.size = hlsl->content_size;
|
||||
compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL;
|
||||
compile_info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE;
|
||||
compile_info.log_level = VKD3D_SHADER_LOG_WARNING;
|
||||
|
||||
compile_info.next = &hlsl_source_info;
|
||||
hlsl_source_info.profile = profile;
|
||||
|
||||
ret = vkd3d_shader_compile(&compile_info, sm1, &messages);
|
||||
if (messages && *messages && FIXME_ON(d3d_shader))
|
||||
{
|
||||
const char *ptr, *end, *line;
|
||||
|
||||
FIXME("Shader log:\n");
|
||||
ptr = messages;
|
||||
end = ptr + strlen(ptr);
|
||||
while ((line = wined3d_get_line(&ptr, end)))
|
||||
FIXME(" %.*s", (int)(ptr - line), line);
|
||||
FIXME("\n");
|
||||
}
|
||||
vkd3d_shader_free_messages(messages);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ERR("Failed to compile HLSL, ret %d.\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffp_hlsl_compile_vs(const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader_desc *shader_desc)
|
||||
{
|
||||
struct wined3d_string_buffer string;
|
||||
struct vkd3d_shader_code sm1;
|
||||
|
||||
if (!string_buffer_init(&string))
|
||||
return false;
|
||||
|
||||
if (!ffp_hlsl_generate_vertex_shader(settings, &string))
|
||||
{
|
||||
string_buffer_free(&string);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!compile_hlsl_shader(&string, &sm1, "vs_2_0"))
|
||||
{
|
||||
string_buffer_free(&string);
|
||||
return false;
|
||||
}
|
||||
string_buffer_free(&string);
|
||||
|
||||
shader_desc->byte_code = sm1.code;
|
||||
shader_desc->byte_code_size = ~(size_t)0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffp_hlsl_compile_ps(const struct ffp_frag_settings *settings, struct wined3d_shader_desc *shader_desc)
|
||||
{
|
||||
struct wined3d_string_buffer string;
|
||||
struct vkd3d_shader_code sm1;
|
||||
|
||||
if (!string_buffer_init(&string))
|
||||
return false;
|
||||
|
||||
if (!ffp_hlsl_generate_pixel_shader(settings, &string))
|
||||
{
|
||||
string_buffer_free(&string);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!compile_hlsl_shader(&string, &sm1, "ps_2_0"))
|
||||
{
|
||||
string_buffer_free(&string);
|
||||
return false;
|
||||
}
|
||||
string_buffer_free(&string);
|
||||
|
||||
shader_desc->byte_code = sm1.code;
|
||||
shader_desc->byte_code_size = ~(size_t)0;
|
||||
return true;
|
||||
}
|
|
@ -1735,17 +1735,38 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv,
|
|||
constant_version = prog->constant_version;
|
||||
update_mask = context->constant_update_mask & prog->constant_update_mask;
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_VS_F)
|
||||
shader_glsl_load_constants_f(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F],
|
||||
prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
|
||||
if (vshader && vshader->is_ffp_vs)
|
||||
{
|
||||
/* The shader's constant update mask is WINED3D_SHADER_CONST_VS_F.
|
||||
* This may be set from shader_glsl_update_graphics_program().
|
||||
* However, we also need to update constants when FFP flags change. */
|
||||
static const uint32_t vs_update_mask = WINED3D_SHADER_CONST_VS_F
|
||||
| WINED3D_SHADER_CONST_FFP_LIGHTS
|
||||
| WINED3D_SHADER_CONST_FFP_MATERIAL
|
||||
| WINED3D_SHADER_CONST_FFP_MODELVIEW
|
||||
| WINED3D_SHADER_CONST_FFP_PROJ
|
||||
| WINED3D_SHADER_CONST_FFP_TEXMATRIX
|
||||
| WINED3D_SHADER_CONST_FFP_VERTEXBLEND
|
||||
| WINED3D_SHADER_CONST_VS_POINTSIZE;
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_VS_I)
|
||||
shader_glsl_load_constants_i(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I],
|
||||
prog->vs.uniform_i_locations, vshader->reg_maps.integer_constants);
|
||||
if (context->constant_update_mask & vs_update_mask)
|
||||
shader_glsl_load_constants_f(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_FFP],
|
||||
prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_mask & WINED3D_SHADER_CONST_VS_F)
|
||||
shader_glsl_load_constants_f(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F],
|
||||
prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_VS_B)
|
||||
shader_glsl_load_constants_b(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B],
|
||||
prog->vs.uniform_b_locations, vshader->reg_maps.boolean_constants);
|
||||
if (update_mask & WINED3D_SHADER_CONST_VS_I)
|
||||
shader_glsl_load_constants_i(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I],
|
||||
prog->vs.uniform_i_locations, vshader->reg_maps.integer_constants);
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_VS_B)
|
||||
shader_glsl_load_constants_b(vshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B],
|
||||
prog->vs.uniform_b_locations, vshader->reg_maps.boolean_constants);
|
||||
}
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES)
|
||||
{
|
||||
|
@ -1890,17 +1911,30 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv,
|
|||
WINED3D_LIGHT_PARALLELPOINT, &constants->light.lights[i], prog);
|
||||
}
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_PS_F)
|
||||
shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F],
|
||||
prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
|
||||
if (pshader && pshader->is_ffp_ps)
|
||||
{
|
||||
static const uint32_t ps_update_mask = WINED3D_SHADER_CONST_PS_F
|
||||
| WINED3D_SHADER_CONST_FFP_COLOR_KEY
|
||||
| WINED3D_SHADER_CONST_FFP_PS;
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_PS_I)
|
||||
shader_glsl_load_constants_i(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I],
|
||||
prog->ps.uniform_i_locations, pshader->reg_maps.integer_constants);
|
||||
if (context->constant_update_mask & ps_update_mask)
|
||||
shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP],
|
||||
prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_mask & WINED3D_SHADER_CONST_PS_F)
|
||||
shader_glsl_load_constants_f(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F],
|
||||
prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_PS_B)
|
||||
shader_glsl_load_constants_b(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B],
|
||||
prog->ps.uniform_b_locations, pshader->reg_maps.boolean_constants);
|
||||
if (update_mask & WINED3D_SHADER_CONST_PS_I)
|
||||
shader_glsl_load_constants_i(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I],
|
||||
prog->ps.uniform_i_locations, pshader->reg_maps.integer_constants);
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_PS_B)
|
||||
shader_glsl_load_constants_b(pshader, context_gl, device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B],
|
||||
prog->ps.uniform_b_locations, pshader->reg_maps.boolean_constants);
|
||||
}
|
||||
|
||||
if (update_mask & WINED3D_SHADER_CONST_PS_BUMP_ENV)
|
||||
{
|
||||
|
@ -10391,10 +10425,10 @@ static void set_glsl_shader_program(const struct wined3d_context_gl *context_gl,
|
|||
vs_id = ctx_data->glsl_program->vs.id;
|
||||
vs_list = &ctx_data->glsl_program->vs.shader_entry;
|
||||
|
||||
if (use_vs(state))
|
||||
if (use_vs(state) || d3d_info->ffp_hlsl)
|
||||
vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
|
||||
}
|
||||
else if (use_vs(state))
|
||||
else if (use_vs(state) || d3d_info->ffp_hlsl)
|
||||
{
|
||||
struct vs_compile_args vs_compile_args;
|
||||
|
||||
|
@ -12113,7 +12147,7 @@ static void glsl_fragment_pipe_fogparams(struct wined3d_context *context,
|
|||
static void glsl_fragment_pipe_fog(struct wined3d_context *context,
|
||||
const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
BOOL use_vshader = use_vs(state);
|
||||
BOOL use_vshader = use_vs(state) && !state->shader[WINED3D_SHADER_TYPE_VERTEX]->is_ffp_vs;
|
||||
enum fogsource new_source;
|
||||
DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
|
||||
DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
|
||||
|
|
|
@ -2268,7 +2268,55 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
|
|||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT shader_set_function(struct wined3d_shader *shader,
|
||||
static void shader_trace(const void *code, size_t size, enum vkd3d_shader_source_type source_type)
|
||||
{
|
||||
struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
|
||||
struct vkd3d_shader_code d3d_asm;
|
||||
const char *ptr, *end, *line;
|
||||
char *messages;
|
||||
int ret;
|
||||
|
||||
static const struct vkd3d_shader_compile_option compile_options[] =
|
||||
{
|
||||
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_6},
|
||||
};
|
||||
|
||||
info.source.code = code;
|
||||
info.source.size = size;
|
||||
info.source_type = source_type;
|
||||
info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
|
||||
info.options = compile_options;
|
||||
info.option_count = ARRAY_SIZE(compile_options);
|
||||
info.log_level = VKD3D_SHADER_LOG_WARNING;
|
||||
|
||||
ret = vkd3d_shader_compile(&info, &d3d_asm, &messages);
|
||||
if (messages && *messages && FIXME_ON(d3d_shader))
|
||||
{
|
||||
FIXME("Shader log:\n");
|
||||
ptr = messages;
|
||||
end = ptr + strlen(ptr);
|
||||
while ((line = wined3d_get_line(&ptr, end)))
|
||||
FIXME(" %.*s", (int)(ptr - line), line);
|
||||
FIXME("\n");
|
||||
}
|
||||
vkd3d_shader_free_messages(messages);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ERR("Failed to disassemble, ret %d.\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = d3d_asm.code;
|
||||
end = ptr + d3d_asm.size;
|
||||
while ((line = wined3d_get_line(&ptr, end)))
|
||||
TRACE(" %.*s", (int)(ptr - line), line);
|
||||
TRACE("\n");
|
||||
|
||||
vkd3d_shader_free_shader_code(&d3d_asm);
|
||||
}
|
||||
|
||||
static HRESULT shader_set_function(struct wined3d_shader *shader, const struct wined3d_shader_desc *desc,
|
||||
enum wined3d_shader_type type, const struct wined3d_stream_output_desc *so_desc, unsigned int float_const_count)
|
||||
{
|
||||
const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
|
||||
|
@ -2279,8 +2327,88 @@ static HRESULT shader_set_function(struct wined3d_shader *shader,
|
|||
unsigned int backend_version;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("shader %p, type %s, float_const_count %u.\n",
|
||||
shader, debug_shader_type(type), float_const_count);
|
||||
TRACE("shader %p, byte_code %p, size %#Ix, type %s, float_const_count %u.\n",
|
||||
shader, desc->byte_code, desc->byte_code_size, debug_shader_type(type), float_const_count);
|
||||
|
||||
if (!desc->byte_code)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (desc->byte_code_size == ~(size_t)0)
|
||||
{
|
||||
struct wined3d_shader_version shader_version;
|
||||
const struct wined3d_shader_frontend *fe;
|
||||
struct wined3d_shader_instruction ins;
|
||||
const DWORD *ptr;
|
||||
void *fe_data;
|
||||
|
||||
shader->source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
|
||||
if (!(shader->frontend = shader_select_frontend(shader->source_type)))
|
||||
{
|
||||
FIXME("Unable to find frontend for shader.\n");
|
||||
shader_cleanup(shader);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
fe = shader->frontend;
|
||||
if (!(fe_data = fe->shader_init(desc->byte_code, desc->byte_code_size, &shader->output_signature)))
|
||||
{
|
||||
WARN("Failed to initialise frontend data.\n");
|
||||
shader_cleanup(shader);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
fe->shader_read_header(fe_data, &ptr, &shader_version);
|
||||
while (!fe->shader_is_end(fe_data, &ptr))
|
||||
fe->shader_read_instruction(fe_data, &ptr, &ins);
|
||||
|
||||
fe->shader_free(fe_data);
|
||||
|
||||
shader->byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr);
|
||||
|
||||
if (!(shader->byte_code = malloc(shader->byte_code_size)))
|
||||
{
|
||||
shader_cleanup(shader);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(shader->byte_code, desc->byte_code, shader->byte_code_size);
|
||||
|
||||
shader->function = shader->byte_code;
|
||||
shader->functionLength = shader->byte_code_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int max_version;
|
||||
|
||||
if (!(shader->byte_code = malloc(desc->byte_code_size)))
|
||||
{
|
||||
shader_cleanup(shader);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(shader->byte_code, desc->byte_code, desc->byte_code_size);
|
||||
shader->byte_code_size = desc->byte_code_size;
|
||||
|
||||
max_version = shader_max_version_from_feature_level(shader->device->cs->c.state->feature_level);
|
||||
if (FAILED(hr = wined3d_shader_extract_from_dxbc(shader, max_version, &shader->source_type)))
|
||||
{
|
||||
shader_cleanup(shader);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!(shader->frontend = shader_select_frontend(shader->source_type)))
|
||||
{
|
||||
FIXME("Unable to find frontend for shader.\n");
|
||||
shader_cleanup(shader);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
}
|
||||
|
||||
if (TRACE_ON(d3d_shader))
|
||||
{
|
||||
if (shader->source_type == VKD3D_SHADER_SOURCE_D3D_BYTECODE)
|
||||
shader_trace(shader->function, shader->functionLength, shader->source_type);
|
||||
else
|
||||
shader_trace(shader->byte_code, shader->byte_code_size, shader->source_type);
|
||||
}
|
||||
|
||||
if (type == WINED3D_SHADER_TYPE_GEOMETRY)
|
||||
{
|
||||
|
@ -2308,7 +2436,8 @@ static HRESULT shader_set_function(struct wined3d_shader *shader,
|
|||
WARN("Wrong shader type %s.\n", debug_shader_type(reg_maps->shader_version.type));
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
if (version->major > shader_max_version_from_feature_level(shader->device->cs->c.state->feature_level))
|
||||
if (!shader->is_ffp_vs && !shader->is_ffp_ps
|
||||
&& version->major > shader_max_version_from_feature_level(shader->device->cs->c.state->feature_level))
|
||||
{
|
||||
WARN("Shader version %u not supported by this device.\n", version->major);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
@ -2421,6 +2550,30 @@ static void wined3d_shader_init_object(void *object)
|
|||
|
||||
list_add_head(&device->shaders, &shader->shader_list_entry);
|
||||
|
||||
if (shader->is_ffp_vs)
|
||||
{
|
||||
struct wined3d_ffp_vs_settings *settings = shader->byte_code;
|
||||
struct wined3d_shader_desc desc;
|
||||
|
||||
if (!ffp_hlsl_compile_vs(settings, &desc))
|
||||
return;
|
||||
free(settings);
|
||||
shader_set_function(shader, &desc, WINED3D_SHADER_TYPE_VERTEX, NULL,
|
||||
device->adapter->d3d_info.limits.vs_uniform_count);
|
||||
}
|
||||
|
||||
if (shader->is_ffp_ps)
|
||||
{
|
||||
struct ffp_frag_settings *settings = shader->byte_code;
|
||||
struct wined3d_shader_desc desc;
|
||||
|
||||
if (!ffp_hlsl_compile_ps(settings, &desc))
|
||||
return;
|
||||
free(settings);
|
||||
shader_set_function(shader, &desc, WINED3D_SHADER_TYPE_PIXEL, NULL,
|
||||
device->adapter->d3d_info.limits.ps_uniform_count);
|
||||
}
|
||||
|
||||
device->shader_backend->shader_precompile(device->shader_priv, shader);
|
||||
}
|
||||
|
||||
|
@ -2548,9 +2701,27 @@ void find_vs_compile_args(const struct wined3d_state *state, const struct wined3
|
|||
&& state->transforms[WINED3D_TS_PROJECTION]._24 == 0.0f
|
||||
&& state->transforms[WINED3D_TS_PROJECTION]._34 == 0.0f
|
||||
&& state->transforms[WINED3D_TS_PROJECTION]._44 == 1.0f)
|
||||
args->fog_src = VS_FOG_Z;
|
||||
{
|
||||
/* Fog source is vertex output Z.
|
||||
*
|
||||
* However, if drawing RHW (which means we are using an HLSL
|
||||
* replacement shader, since we got here), and depth testing is
|
||||
* disabled, primitives are not supposed to be clipped by the
|
||||
* viewport. We handle this in the vertex shader by essentially
|
||||
* flushing output Z to zero.
|
||||
*
|
||||
* Fog needs to still read from the original Z, however. In this
|
||||
* case we read from oFog, which contains the original Z. */
|
||||
|
||||
if (state->vertex_declaration->position_transformed)
|
||||
args->fog_src = VS_FOG_COORD;
|
||||
else
|
||||
args->fog_src = VS_FOG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
args->fog_src = VS_FOG_W;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2613,71 +2784,9 @@ bool vshader_get_input(const struct wined3d_shader *shader,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void shader_trace(const void *code, size_t size, enum vkd3d_shader_source_type source_type)
|
||||
static void shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
|
||||
void *parent, const struct wined3d_parent_ops *parent_ops)
|
||||
{
|
||||
struct vkd3d_shader_compile_info info;
|
||||
struct vkd3d_shader_code d3d_asm;
|
||||
const char *ptr, *end, *line;
|
||||
char *messages;
|
||||
int ret;
|
||||
|
||||
static const struct vkd3d_shader_compile_option compile_options[] =
|
||||
{
|
||||
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_6},
|
||||
};
|
||||
|
||||
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
|
||||
info.next = NULL;
|
||||
info.source.code = code;
|
||||
info.source.size = size;
|
||||
info.source_type = source_type;
|
||||
info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
|
||||
info.options = compile_options;
|
||||
info.option_count = ARRAY_SIZE(compile_options);
|
||||
info.log_level = VKD3D_SHADER_LOG_WARNING;
|
||||
info.source_name = NULL;
|
||||
|
||||
ret = vkd3d_shader_compile(&info, &d3d_asm, &messages);
|
||||
if (messages && *messages && FIXME_ON(d3d_shader))
|
||||
{
|
||||
FIXME("Shader log:\n");
|
||||
ptr = messages;
|
||||
end = ptr + strlen(ptr);
|
||||
while ((line = wined3d_get_line(&ptr, end)))
|
||||
{
|
||||
FIXME(" %.*s", (int)(ptr - line), line);
|
||||
}
|
||||
FIXME("\n");
|
||||
}
|
||||
vkd3d_shader_free_messages(messages);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ERR("Failed to disassemble, ret %d.\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = d3d_asm.code;
|
||||
end = ptr + d3d_asm.size;
|
||||
while ((line = wined3d_get_line(&ptr, end)))
|
||||
{
|
||||
TRACE(" %.*s", (int)(ptr - line), line);
|
||||
}
|
||||
TRACE("\n");
|
||||
|
||||
vkd3d_shader_free_shader_code(&d3d_asm);
|
||||
}
|
||||
|
||||
static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
|
||||
const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("byte_code %p, byte_code_size %#lx.\n", desc->byte_code, (long)desc->byte_code_size);
|
||||
|
||||
if (!desc->byte_code)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
shader->ref = 1;
|
||||
shader->device = device;
|
||||
shader->parent = parent;
|
||||
|
@ -2690,87 +2799,6 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
|
|||
shader->lconst_inf_or_nan = FALSE;
|
||||
list_init(&shader->reg_maps.indexable_temps);
|
||||
list_init(&shader->shader_list_entry);
|
||||
|
||||
if (desc->byte_code_size == ~(size_t)0)
|
||||
{
|
||||
struct wined3d_shader_version shader_version;
|
||||
const struct wined3d_shader_frontend *fe;
|
||||
struct wined3d_shader_instruction ins;
|
||||
const DWORD *ptr;
|
||||
void *fe_data;
|
||||
|
||||
shader->source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
|
||||
if (!(shader->frontend = shader_select_frontend(shader->source_type)))
|
||||
{
|
||||
FIXME("Unable to find frontend for shader.\n");
|
||||
hr = WINED3DERR_INVALIDCALL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fe = shader->frontend;
|
||||
if (!(fe_data = fe->shader_init(desc->byte_code, desc->byte_code_size, &shader->output_signature)))
|
||||
{
|
||||
WARN("Failed to initialise frontend data.\n");
|
||||
hr = WINED3DERR_INVALIDCALL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fe->shader_read_header(fe_data, &ptr, &shader_version);
|
||||
while (!fe->shader_is_end(fe_data, &ptr))
|
||||
fe->shader_read_instruction(fe_data, &ptr, &ins);
|
||||
|
||||
fe->shader_free(fe_data);
|
||||
|
||||
shader->byte_code_size = (ptr - desc->byte_code) * sizeof(*ptr);
|
||||
|
||||
if (!(shader->byte_code = malloc(shader->byte_code_size)))
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
memcpy(shader->byte_code, desc->byte_code, shader->byte_code_size);
|
||||
|
||||
shader->function = shader->byte_code;
|
||||
shader->functionLength = shader->byte_code_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int max_version;
|
||||
|
||||
if (!(shader->byte_code = malloc(desc->byte_code_size)))
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
memcpy(shader->byte_code, desc->byte_code, desc->byte_code_size);
|
||||
shader->byte_code_size = desc->byte_code_size;
|
||||
|
||||
max_version = shader_max_version_from_feature_level(device->cs->c.state->feature_level);
|
||||
if (FAILED(hr = wined3d_shader_extract_from_dxbc(shader, max_version, &shader->source_type)))
|
||||
goto fail;
|
||||
|
||||
if (!(shader->frontend = shader_select_frontend(shader->source_type)))
|
||||
{
|
||||
FIXME("Unable to find frontend for shader.\n");
|
||||
hr = WINED3DERR_INVALIDCALL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (TRACE_ON(d3d_shader))
|
||||
{
|
||||
if (shader->source_type == VKD3D_SHADER_SOURCE_D3D_BYTECODE)
|
||||
shader_trace(shader->function, shader->functionLength, shader->source_type);
|
||||
else
|
||||
shader_trace(shader->byte_code, shader->byte_code_size, shader->source_type);
|
||||
}
|
||||
|
||||
|
||||
return WINED3D_OK;
|
||||
|
||||
fail:
|
||||
shader_cleanup(shader);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
|
||||
|
@ -2778,10 +2806,9 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_
|
|||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops)))
|
||||
return hr;
|
||||
shader_init(shader, device, parent, parent_ops);
|
||||
|
||||
if (FAILED(hr = shader_set_function(shader,
|
||||
if (FAILED(hr = shader_set_function(shader, desc,
|
||||
WINED3D_SHADER_TYPE_VERTEX, NULL, device->adapter->d3d_info.limits.vs_uniform_count)))
|
||||
{
|
||||
shader_cleanup(shader);
|
||||
|
@ -2797,10 +2824,9 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3
|
|||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops)))
|
||||
return hr;
|
||||
shader_init(shader, device, parent, parent_ops);
|
||||
|
||||
if (FAILED(hr = shader_set_function(shader, WINED3D_SHADER_TYPE_GEOMETRY, so_desc, 0)))
|
||||
if (FAILED(hr = shader_set_function(shader, desc, WINED3D_SHADER_TYPE_GEOMETRY, so_desc, 0)))
|
||||
goto fail;
|
||||
|
||||
return WINED3D_OK;
|
||||
|
@ -2846,6 +2872,7 @@ void find_gs_compile_args(const struct wined3d_state *state, const struct wined3
|
|||
void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
|
||||
BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context)
|
||||
{
|
||||
const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
|
||||
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
|
||||
struct wined3d_shader_resource_view *view;
|
||||
struct wined3d_texture *texture;
|
||||
|
@ -2873,7 +2900,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
|
|||
{
|
||||
uint32_t tex_transform = flags & ~WINED3D_TTFF_PROJECTED;
|
||||
|
||||
if (!state->shader[WINED3D_SHADER_TYPE_VERTEX])
|
||||
if (!vs || vs->is_ffp_vs)
|
||||
{
|
||||
enum wined3d_shader_resource_type resource_type = shader->reg_maps.resource_info[i].type;
|
||||
unsigned int j;
|
||||
|
@ -3043,7 +3070,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
|
|||
switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
|
||||
{
|
||||
case WINED3D_FOG_NONE:
|
||||
if (position_transformed || use_vs(state))
|
||||
if (position_transformed || (vs && !vs->is_ffp_vs))
|
||||
{
|
||||
args->fog = WINED3D_FFP_PS_FOG_LINEAR;
|
||||
break;
|
||||
|
@ -3127,10 +3154,9 @@ static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_d
|
|||
const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = shader_init(shader, device, desc, parent, parent_ops)))
|
||||
return hr;
|
||||
shader_init(shader, device, parent, parent_ops);
|
||||
|
||||
if (FAILED(hr = shader_set_function(shader,
|
||||
if (FAILED(hr = shader_set_function(shader, desc,
|
||||
WINED3D_SHADER_TYPE_PIXEL, NULL, d3d_info->limits.ps_uniform_count)))
|
||||
{
|
||||
shader_cleanup(shader);
|
||||
|
@ -3175,14 +3201,9 @@ HRESULT CDECL wined3d_shader_create_cs(struct wined3d_device *device, const stru
|
|||
if (!(object = calloc(1, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (FAILED(hr = shader_init(object, device, desc, parent, parent_ops)))
|
||||
{
|
||||
WARN("Failed to initialize compute shader, hr %#lx.\n", hr);
|
||||
free(object);
|
||||
return hr;
|
||||
}
|
||||
shader_init(object, device, parent, parent_ops);
|
||||
|
||||
if (FAILED(hr = shader_set_function(object, WINED3D_SHADER_TYPE_COMPUTE, NULL, 0)))
|
||||
if (FAILED(hr = shader_set_function(object, desc, WINED3D_SHADER_TYPE_COMPUTE, NULL, 0)))
|
||||
{
|
||||
shader_cleanup(object);
|
||||
free(object);
|
||||
|
@ -3209,14 +3230,9 @@ HRESULT CDECL wined3d_shader_create_ds(struct wined3d_device *device, const stru
|
|||
if (!(object = calloc(1, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (FAILED(hr = shader_init(object, device, desc, parent, parent_ops)))
|
||||
{
|
||||
WARN("Failed to initialize domain shader, hr %#lx.\n", hr);
|
||||
free(object);
|
||||
return hr;
|
||||
}
|
||||
shader_init(object, device, parent, parent_ops);
|
||||
|
||||
if (FAILED(hr = shader_set_function(object, WINED3D_SHADER_TYPE_DOMAIN, NULL, 0)))
|
||||
if (FAILED(hr = shader_set_function(object, desc, WINED3D_SHADER_TYPE_DOMAIN, NULL, 0)))
|
||||
{
|
||||
shader_cleanup(object);
|
||||
free(object);
|
||||
|
@ -3271,14 +3287,9 @@ HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const stru
|
|||
if (!(object = calloc(1, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (FAILED(hr = shader_init(object, device, desc, parent, parent_ops)))
|
||||
{
|
||||
WARN("Failed to initialize hull shader, hr %#lx.\n", hr);
|
||||
free(object);
|
||||
return hr;
|
||||
}
|
||||
shader_init(object, device, parent, parent_ops);
|
||||
|
||||
if (FAILED(hr = shader_set_function(object, WINED3D_SHADER_TYPE_HULL, NULL, 0)))
|
||||
if (FAILED(hr = shader_set_function(object, desc, WINED3D_SHADER_TYPE_HULL, NULL, 0)))
|
||||
{
|
||||
shader_cleanup(object);
|
||||
free(object);
|
||||
|
@ -3346,3 +3357,53 @@ HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const stru
|
|||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
HRESULT wined3d_shader_create_ffp_vs(struct wined3d_device *device,
|
||||
const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader **shader)
|
||||
{
|
||||
struct wined3d_shader *object;
|
||||
|
||||
if (!(object = calloc(1, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
shader_init(object, device, NULL, &wined3d_null_parent_ops);
|
||||
object->is_ffp_vs = true;
|
||||
if (!(object->byte_code = malloc(sizeof(*settings))))
|
||||
{
|
||||
free(object);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(object->byte_code, settings, sizeof(*settings));
|
||||
|
||||
wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
|
||||
|
||||
TRACE("Created FFP vertex shader %p.\n", object);
|
||||
*shader = object;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
HRESULT wined3d_shader_create_ffp_ps(struct wined3d_device *device,
|
||||
const struct ffp_frag_settings *settings, struct wined3d_shader **shader)
|
||||
{
|
||||
struct wined3d_shader *object;
|
||||
|
||||
if (!(object = calloc(1, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
shader_init(object, device, NULL, &wined3d_null_parent_ops);
|
||||
object->is_ffp_ps = true;
|
||||
if (!(object->byte_code = malloc(sizeof(*settings))))
|
||||
{
|
||||
free(object);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(object->byte_code, settings, sizeof(*settings));
|
||||
|
||||
wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
|
||||
|
||||
TRACE("Created FFP pixel shader %p.\n", object);
|
||||
*shader = object;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Copyright 2005 Oliver Stieber
|
||||
* Copyright 2007 Stefan Dösinger for CodeWeavers
|
||||
* Copyright 2009 Henri Verbeet for CodeWeavers
|
||||
* Copyright 2019,2020,2022 Zebediah Figura for CodeWeavers
|
||||
* Copyright 2019,2020,2022-2024 Elizabeth Figura for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -1299,6 +1299,7 @@ void CDECL wined3d_stateblock_set_vertex_shader(struct wined3d_stateblock *state
|
|||
wined3d_shader_decref(stateblock->stateblock_state.vs);
|
||||
stateblock->stateblock_state.vs = shader;
|
||||
stateblock->changed.vertexShader = TRUE;
|
||||
stateblock->changed.ffp_vs_settings = 1;
|
||||
}
|
||||
|
||||
static void wined3d_bitmap_set_bits(uint32_t *bitmap, unsigned int start, unsigned int count)
|
||||
|
@ -1439,6 +1440,7 @@ void CDECL wined3d_stateblock_set_pixel_shader(struct wined3d_stateblock *stateb
|
|||
wined3d_shader_decref(stateblock->stateblock_state.ps);
|
||||
stateblock->stateblock_state.ps = shader;
|
||||
stateblock->changed.pixelShader = TRUE;
|
||||
stateblock->changed.ffp_ps_settings = 1;
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_stateblock_set_ps_consts_f(struct wined3d_stateblock *stateblock,
|
||||
|
@ -1573,6 +1575,9 @@ void CDECL wined3d_stateblock_set_vertex_declaration(struct wined3d_stateblock *
|
|||
|| declaration->normal != prev->normal || declaration->point_size != prev->point_size)
|
||||
stateblock->changed.ffp_vs_settings = 1;
|
||||
}
|
||||
|
||||
if (declaration->position_transformed != prev->position_transformed)
|
||||
stateblock->changed.ffp_vs_settings = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2379,10 +2384,10 @@ static void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state
|
|||
|
||||
}
|
||||
|
||||
/* FFP push constant buffers do not have a "default" state on the CS side.
|
||||
* We need to explicitly invalidate them when initializing the context or
|
||||
* resetting. */
|
||||
static void wined3d_stateblock_invalidate_push_constants(struct wined3d_stateblock *stateblock)
|
||||
/* Some states, e.g. FFP push constant buffers, do not have a "default" state
|
||||
* on the CS side. We need to explicitly invalidate them when initializing the
|
||||
* context or resetting. */
|
||||
static void wined3d_stateblock_invalidate_initial_states(struct wined3d_stateblock *stateblock)
|
||||
{
|
||||
stateblock->changed.ffp_ps_constants = 1;
|
||||
stateblock->changed.lights = 1;
|
||||
|
@ -2392,6 +2397,8 @@ static void wined3d_stateblock_invalidate_push_constants(struct wined3d_stateblo
|
|||
memset(stateblock->changed.transform, 0xff, sizeof(stateblock->changed.transform));
|
||||
stateblock->changed.modelview_matrices = 1;
|
||||
stateblock->changed.point_scale = 1;
|
||||
stateblock->changed.ffp_vs_settings = 1;
|
||||
stateblock->changed.ffp_ps_settings = 1;
|
||||
}
|
||||
|
||||
static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const struct wined3d_stateblock *device_state,
|
||||
|
@ -2409,7 +2416,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru
|
|||
list_init(&stateblock->changed.changed_lights);
|
||||
|
||||
if (type == WINED3D_SBT_PRIMARY)
|
||||
wined3d_stateblock_invalidate_push_constants(stateblock);
|
||||
wined3d_stateblock_invalidate_initial_states(stateblock);
|
||||
|
||||
if (type == WINED3D_SBT_RECORDED || type == WINED3D_SBT_PRIMARY)
|
||||
return WINED3D_OK;
|
||||
|
@ -2486,7 +2493,7 @@ void CDECL wined3d_stateblock_reset(struct wined3d_stateblock *stateblock)
|
|||
memset(&stateblock->stateblock_state, 0, sizeof(stateblock->stateblock_state));
|
||||
stateblock->stateblock_state.light_state = &stateblock->light_state;
|
||||
wined3d_stateblock_state_init(&stateblock->stateblock_state, stateblock->device, WINED3D_STATE_INIT_DEFAULT);
|
||||
wined3d_stateblock_invalidate_push_constants(stateblock);
|
||||
wined3d_stateblock_invalidate_initial_states(stateblock);
|
||||
}
|
||||
|
||||
static void wined3d_device_set_base_vertex_index(struct wined3d_device *device, int base_index)
|
||||
|
@ -2909,6 +2916,65 @@ void CDECL wined3d_stateblock_apply_clear_state(struct wined3d_stateblock *state
|
|||
wined3d_device_set_render_state(device, WINED3D_RS_SRGBWRITEENABLE, state->rs[WINED3D_RS_SRGBWRITEENABLE]);
|
||||
}
|
||||
|
||||
static struct wined3d_shader *get_ffp_vertex_shader(struct wined3d_device *device, const struct wined3d_state *state)
|
||||
{
|
||||
static const struct wined3d_stream_info dummy_stream_info;
|
||||
struct wined3d_ffp_vs_settings settings;
|
||||
const struct wine_rb_entry *entry;
|
||||
struct wined3d_ffp_vs *vs;
|
||||
|
||||
/* XXX: wined3d_ffp_get_vs_settings() only needs the stream info for the
|
||||
* swizzle map, which the HLSL pipeline doesn't use (it will be computed and
|
||||
* used later as part of struct vs_compile_args).
|
||||
*
|
||||
* This is nevertheless janky, and we'd like to get rid of it. Eventually
|
||||
* once the HLSL backend is used everywhere, we can get rid of the swizzle
|
||||
* map from wined3d_ffp_vs_settings. */
|
||||
wined3d_ffp_get_vs_settings(state, &dummy_stream_info, &device->adapter->d3d_info, &settings);
|
||||
|
||||
if ((entry = wine_rb_get(&device->ffp_vertex_shaders, &settings)))
|
||||
return WINE_RB_ENTRY_VALUE(entry, struct wined3d_ffp_vs, entry.entry)->shader;
|
||||
|
||||
if (!(vs = malloc(sizeof(*vs))))
|
||||
return NULL;
|
||||
|
||||
vs->entry.settings = settings;
|
||||
if (FAILED(wined3d_shader_create_ffp_vs(device, &settings, &vs->shader)))
|
||||
{
|
||||
free(vs);
|
||||
return NULL;
|
||||
}
|
||||
if (wine_rb_put(&device->ffp_vertex_shaders, &vs->entry.settings, &vs->entry.entry) == -1)
|
||||
ERR("Failed to insert FFP vertex shader.\n");
|
||||
|
||||
return vs->shader;
|
||||
}
|
||||
|
||||
static struct wined3d_shader *get_ffp_pixel_shader(struct wined3d_device *device, const struct wined3d_state *state)
|
||||
{
|
||||
struct ffp_frag_settings settings;
|
||||
const struct ffp_frag_desc *desc;
|
||||
struct wined3d_ffp_ps *ps;
|
||||
|
||||
wined3d_ffp_get_fs_settings(state, &device->adapter->d3d_info, &settings);
|
||||
|
||||
if ((desc = find_ffp_frag_shader(&device->ffp_pixel_shaders, &settings)))
|
||||
return CONTAINING_RECORD(desc, struct wined3d_ffp_ps, entry)->shader;
|
||||
|
||||
if (!(ps = malloc(sizeof(*ps))))
|
||||
return NULL;
|
||||
|
||||
ps->entry.settings = settings;
|
||||
if (FAILED(wined3d_shader_create_ffp_ps(device, &settings, &ps->shader)))
|
||||
{
|
||||
free(ps);
|
||||
return NULL;
|
||||
}
|
||||
add_ffp_frag_shader(&device->ffp_pixel_shaders, &ps->entry);
|
||||
|
||||
return ps->shader;
|
||||
}
|
||||
|
||||
void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
|
||||
struct wined3d_stateblock *stateblock)
|
||||
{
|
||||
|
@ -3746,16 +3812,40 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
|
|||
WINED3D_SHADER_CONST_FFP_PS, 0, offsetof(struct wined3d_ffp_ps_constants, color_key), &constants);
|
||||
}
|
||||
|
||||
if (changed->ffp_vs_settings && !state->vs)
|
||||
/* XXX: We don't invalidate HLSL shaders for every field contained in
|
||||
* wined3d_ffp_vs_settings / ffp_frag_settings; only the ones that the HLSL
|
||||
* FFP pipeline cares about. The rest should eventually be removed from
|
||||
* those structs and left only in vs_compile_args / ps_compile_args. */
|
||||
|
||||
if (changed->ffp_vs_settings
|
||||
&& (!state->vs || !state->vertex_declaration || state->vertex_declaration->position_transformed))
|
||||
{
|
||||
/* Force invalidation of the vertex shader. */
|
||||
wined3d_device_context_emit_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, NULL);
|
||||
if (device->adapter->d3d_info.ffp_hlsl)
|
||||
{
|
||||
struct wined3d_shader *shader = get_ffp_vertex_shader(device, device->cs->c.state);
|
||||
|
||||
wined3d_device_context_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Force invalidation of the vertex shader. */
|
||||
wined3d_device_context_emit_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed->ffp_ps_settings && !state->ps)
|
||||
{
|
||||
/* Force invalidation of the pixel shader. */
|
||||
wined3d_device_context_emit_set_shader(context, WINED3D_SHADER_TYPE_PIXEL, NULL);
|
||||
if (device->adapter->d3d_info.ffp_hlsl)
|
||||
{
|
||||
struct wined3d_shader *shader = get_ffp_pixel_shader(device, device->cs->c.state);
|
||||
|
||||
wined3d_device_context_set_shader(context, WINED3D_SHADER_TYPE_PIXEL, shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Force invalidation of the pixel shader. */
|
||||
wined3d_device_context_emit_set_shader(context, WINED3D_SHADER_TYPE_PIXEL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
assert(list_empty(&stateblock->changed.changed_lights));
|
||||
|
|
|
@ -6448,7 +6448,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct
|
|||
|
||||
memset(settings, 0, sizeof(*settings));
|
||||
|
||||
if (si->position_transformed)
|
||||
if (vdecl->position_transformed)
|
||||
{
|
||||
settings->transformed = 1;
|
||||
settings->point_size = state->primitive_type == WINED3D_PT_POINTLIST;
|
||||
|
|
|
@ -463,6 +463,11 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
|
|||
TRACE("Forcing all constant buffers to be write-mappable.\n");
|
||||
wined3d_settings.cb_access_map_w = TRUE;
|
||||
}
|
||||
if (!get_config_key_dword(hkey, appkey, env, "ffp_hlsl", &tmpvalue))
|
||||
{
|
||||
ERR_(winediag)("Using the HLSL-based FFP backend.\n");
|
||||
wined3d_settings.ffp_hlsl = tmpvalue;
|
||||
}
|
||||
}
|
||||
|
||||
if (appkey) RegCloseKey( appkey );
|
||||
|
|
|
@ -242,6 +242,7 @@ struct wined3d_d3d_info
|
|||
uint32_t fences : 1;
|
||||
uint32_t persistent_map : 1;
|
||||
uint32_t gpu_push_constants : 1;
|
||||
uint32_t ffp_hlsl : 1;
|
||||
enum wined3d_feature_level feature_level;
|
||||
|
||||
DWORD multisample_draw_location;
|
||||
|
@ -475,7 +476,6 @@ struct wined3d_settings
|
|||
char *logo;
|
||||
unsigned int multisample_textures;
|
||||
unsigned int sample_count;
|
||||
BOOL check_float_constants;
|
||||
unsigned int strict_shader_math;
|
||||
unsigned int max_sm_vs;
|
||||
unsigned int max_sm_hs;
|
||||
|
@ -485,7 +485,9 @@ struct wined3d_settings
|
|||
unsigned int max_sm_cs;
|
||||
enum wined3d_renderer renderer;
|
||||
enum wined3d_shader_backend shader_backend;
|
||||
BOOL cb_access_map_w;
|
||||
bool check_float_constants;
|
||||
bool cb_access_map_w;
|
||||
bool ffp_hlsl;
|
||||
};
|
||||
|
||||
extern struct wined3d_settings wined3d_settings;
|
||||
|
@ -2048,10 +2050,11 @@ void context_state_fb(struct wined3d_context *context,
|
|||
|
||||
struct wined3d_light_constants
|
||||
{
|
||||
/* Padding is needed for the HLSL backend. */
|
||||
struct wined3d_color diffuse, specular, ambient;
|
||||
struct wined3d_vec4 position, direction;
|
||||
float range, falloff, cos_half_theta, cos_half_phi;
|
||||
float const_att, linear_att, quad_att;
|
||||
float const_att, linear_att, quad_att, padding;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -2662,6 +2665,12 @@ struct ffp_frag_desc
|
|||
int wined3d_ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry);
|
||||
int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry);
|
||||
|
||||
struct wined3d_ffp_ps
|
||||
{
|
||||
struct ffp_frag_desc entry;
|
||||
struct wined3d_shader *shader;
|
||||
};
|
||||
|
||||
extern const struct wined3d_parent_ops wined3d_null_parent_ops;
|
||||
|
||||
void wined3d_ffp_get_fs_settings(const struct wined3d_state *state,
|
||||
|
@ -2724,6 +2733,12 @@ struct wined3d_ffp_vs_desc
|
|||
struct wined3d_ffp_vs_settings settings;
|
||||
};
|
||||
|
||||
struct wined3d_ffp_vs
|
||||
{
|
||||
struct wined3d_ffp_vs_desc entry;
|
||||
struct wined3d_shader *shader;
|
||||
};
|
||||
|
||||
void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
|
||||
const struct wined3d_d3d_info *d3d_info, struct wined3d_ffp_vs_settings *settings);
|
||||
|
||||
|
@ -2769,8 +2784,10 @@ struct wined3d_ffp_vs_constants
|
|||
struct wined3d_ffp_point_constants
|
||||
{
|
||||
float scale_const, scale_linear, scale_quad;
|
||||
float padding; /* For the HLSL backend. */
|
||||
} point;
|
||||
struct wined3d_material material;
|
||||
float padding[3]; /* For the HLSL backend. */
|
||||
struct wined3d_ffp_light_constants
|
||||
{
|
||||
struct wined3d_color ambient;
|
||||
|
@ -2983,6 +3000,7 @@ struct wined3d_device
|
|||
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
|
||||
struct wine_rb_tree so_descs;
|
||||
struct wine_rb_tree samplers, rasterizer_states, blend_states, depth_stencil_states;
|
||||
struct wine_rb_tree ffp_vertex_shaders, ffp_pixel_shaders;
|
||||
|
||||
/* Render Target Support */
|
||||
struct wined3d_rendertarget_view *auto_depth_stencil_view;
|
||||
|
@ -4206,7 +4224,9 @@ struct wined3d_shader
|
|||
unsigned int functionLength;
|
||||
void *byte_code;
|
||||
unsigned int byte_code_size;
|
||||
BOOL load_local_constsF;
|
||||
bool load_local_constsF;
|
||||
bool is_ffp_vs;
|
||||
bool is_ffp_ps;
|
||||
enum vkd3d_shader_source_type source_type;
|
||||
const struct wined3d_shader_frontend *frontend;
|
||||
void *frontend_data;
|
||||
|
@ -4244,6 +4264,11 @@ struct wined3d_shader
|
|||
} u;
|
||||
};
|
||||
|
||||
HRESULT wined3d_shader_create_ffp_vs(struct wined3d_device *device,
|
||||
const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader **shader);
|
||||
HRESULT wined3d_shader_create_ffp_ps(struct wined3d_device *device,
|
||||
const struct ffp_frag_settings *settings, struct wined3d_shader **shader);
|
||||
|
||||
enum wined3d_shader_resource_type pixelshader_get_resource_type(const struct wined3d_shader_reg_maps *reg_maps,
|
||||
unsigned int resource_idx, DWORD tex_types);
|
||||
void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
|
||||
|
@ -4273,6 +4298,9 @@ BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage us
|
|||
|
||||
enum vkd3d_shader_visibility vkd3d_shader_visibility_from_wined3d(enum wined3d_shader_type shader_type);
|
||||
|
||||
bool ffp_hlsl_compile_vs(const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader_desc *shader_desc);
|
||||
bool ffp_hlsl_compile_ps(const struct ffp_frag_settings *settings, struct wined3d_shader_desc *shader_desc);
|
||||
|
||||
static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
|
||||
{
|
||||
switch (reg->type)
|
||||
|
|
Loading…
Reference in a new issue