mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
wined3d: Move shader parsing to shader_set_function().
The idea is that we will have wined3d_shader objects that represent shaders not yet in d3d form (specifically, in HLSL form or containing only an FFP settings struct.) Hence we need to make it possible to delay d3d shader parsing, but still keep the rest of shader_init().
This commit is contained in:
parent
d2bed27bfe
commit
2eb7397e23
Notes:
Alexandre Julliard
2024-11-19 23:22:30 +01:00
Approved-by: Jan Sikorski (@jsikorski) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6813
1 changed files with 97 additions and 123 deletions
|
@ -2316,7 +2316,7 @@ static void shader_trace(const void *code, size_t size, enum vkd3d_shader_source
|
|||
vkd3d_shader_free_shader_code(&d3d_asm);
|
||||
}
|
||||
|
||||
static HRESULT shader_set_function(struct wined3d_shader *shader,
|
||||
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;
|
||||
|
@ -2327,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)
|
||||
{
|
||||
|
@ -2661,16 +2741,9 @@ bool vshader_get_input(const struct wined3d_shader *shader,
|
|||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
static void shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
|
||||
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;
|
||||
|
@ -2683,87 +2756,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,
|
||||
|
@ -2771,10 +2763,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);
|
||||
|
@ -2790,10 +2781,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;
|
||||
|
@ -3120,10 +3110,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);
|
||||
|
@ -3168,14 +3157,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);
|
||||
|
@ -3202,14 +3186,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);
|
||||
|
@ -3264,14 +3243,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);
|
||||
|
|
Loading…
Reference in a new issue