mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-09-13 09:16:14 -07:00
vkd3d-shader: Write the SM1 constant table.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f0d2a6d384
commit
b87e9b0652
@ -7,6 +7,7 @@ widl_headers = \
|
||||
include/vkd3d_d3d12.h \
|
||||
include/vkd3d_d3d12sdklayers.h \
|
||||
include/vkd3d_d3dcommon.h \
|
||||
include/vkd3d_d3dx9shader.h \
|
||||
include/vkd3d_dxgi.h \
|
||||
include/vkd3d_dxgi1_2.h \
|
||||
include/vkd3d_dxgi1_3.h \
|
||||
@ -22,6 +23,7 @@ vkd3d_public_headers = \
|
||||
include/vkd3d_d3d9types.h \
|
||||
include/vkd3d_d3dcommon.h \
|
||||
include/vkd3d_d3dcompiler.h \
|
||||
include/vkd3d_d3dx9shader.h \
|
||||
include/vkd3d_dxgibase.h \
|
||||
include/vkd3d_dxgiformat.h \
|
||||
include/vkd3d_shader.h \
|
||||
|
1
include/.gitignore
vendored
1
include/.gitignore
vendored
@ -5,6 +5,7 @@ stamp-h1
|
||||
vkd3d_d3d12.h
|
||||
vkd3d_d3d12sdklayers.h
|
||||
vkd3d_d3dcommon.h
|
||||
vkd3d_d3dx9shader.h
|
||||
vkd3d_dxgi.h
|
||||
vkd3d_dxgi1_2.h
|
||||
vkd3d_dxgi1_3.h
|
||||
|
@ -21,6 +21,12 @@
|
||||
#define __VKD3D_D3D9TYPES_H
|
||||
#ifndef _d3d9TYPES_H_
|
||||
|
||||
#ifndef MAKEFOURCC
|
||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
|
||||
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
|
||||
#endif
|
||||
|
||||
#define D3DPS_VERSION(major, minor) (0xffff0000 | ((major) << 8) | (minor))
|
||||
#define D3DVS_VERSION(major, minor) (0xfffe0000 | ((major) << 8) | (minor))
|
||||
|
||||
|
76
include/vkd3d_d3dx9shader.idl
Normal file
76
include/vkd3d_d3dx9shader.idl
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2008 Luis Busquets
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
import "vkd3d_windows.h";
|
||||
import "vkd3d_d3d9types.h";
|
||||
|
||||
typedef enum _D3DXREGISTER_SET
|
||||
{
|
||||
D3DXRS_BOOL,
|
||||
D3DXRS_INT4,
|
||||
D3DXRS_FLOAT4,
|
||||
D3DXRS_SAMPLER,
|
||||
D3DXRS_FORCE_DWORD = 0x7fffffff,
|
||||
} D3DXREGISTER_SET;
|
||||
|
||||
typedef enum D3DXPARAMETER_CLASS
|
||||
{
|
||||
D3DXPC_SCALAR,
|
||||
D3DXPC_VECTOR,
|
||||
D3DXPC_MATRIX_ROWS,
|
||||
D3DXPC_MATRIX_COLUMNS,
|
||||
D3DXPC_OBJECT,
|
||||
D3DXPC_STRUCT,
|
||||
D3DXPC_FORCE_DWORD = 0x7fffffff,
|
||||
} D3DXPARAMETER_CLASS;
|
||||
|
||||
typedef enum D3DXPARAMETER_TYPE
|
||||
{
|
||||
D3DXPT_VOID,
|
||||
D3DXPT_BOOL,
|
||||
D3DXPT_INT,
|
||||
D3DXPT_FLOAT,
|
||||
D3DXPT_STRING,
|
||||
D3DXPT_TEXTURE,
|
||||
D3DXPT_TEXTURE1D,
|
||||
D3DXPT_TEXTURE2D,
|
||||
D3DXPT_TEXTURE3D,
|
||||
D3DXPT_TEXTURECUBE,
|
||||
D3DXPT_SAMPLER,
|
||||
D3DXPT_SAMPLER1D,
|
||||
D3DXPT_SAMPLER2D,
|
||||
D3DXPT_SAMPLER3D,
|
||||
D3DXPT_SAMPLERCUBE,
|
||||
D3DXPT_PIXELSHADER,
|
||||
D3DXPT_VERTEXSHADER,
|
||||
D3DXPT_PIXELFRAGMENT,
|
||||
D3DXPT_VERTEXFRAGMENT,
|
||||
D3DXPT_UNSUPPORTED,
|
||||
D3DXPT_FORCE_DWORD = 0x7fffffff,
|
||||
} D3DXPARAMETER_TYPE;
|
||||
|
||||
typedef struct _D3DXSHADER_CONSTANTTABLE
|
||||
{
|
||||
DWORD Size;
|
||||
DWORD Creator;
|
||||
DWORD Version;
|
||||
DWORD Constants;
|
||||
DWORD ConstantInfo;
|
||||
DWORD Flags;
|
||||
DWORD Target;
|
||||
} D3DXSHADER_CONSTANTTABLE;
|
@ -115,7 +115,6 @@ struct hlsl_type
|
||||
unsigned int modifiers;
|
||||
unsigned int dimx;
|
||||
unsigned int dimy;
|
||||
unsigned int reg_size;
|
||||
union
|
||||
{
|
||||
struct list *elements;
|
||||
@ -125,6 +124,9 @@ struct hlsl_type
|
||||
unsigned int elements_count;
|
||||
} array;
|
||||
} e;
|
||||
|
||||
unsigned int reg_size;
|
||||
unsigned int bytecode_offset;
|
||||
};
|
||||
|
||||
struct hlsl_struct_field
|
||||
@ -134,7 +136,9 @@ struct hlsl_struct_field
|
||||
struct hlsl_type *type;
|
||||
const char *name;
|
||||
const char *semantic;
|
||||
|
||||
unsigned int reg_offset;
|
||||
unsigned int name_offset;
|
||||
};
|
||||
|
||||
struct hlsl_reg
|
||||
@ -221,6 +225,7 @@ struct hlsl_ir_var
|
||||
uint32_t is_input_varying : 1;
|
||||
uint32_t is_output_varying : 1;
|
||||
uint32_t is_uniform : 1;
|
||||
uint32_t is_param : 1;
|
||||
};
|
||||
|
||||
struct hlsl_ir_function
|
||||
|
@ -765,6 +765,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list,
|
||||
|
||||
if (!(var = hlsl_new_var(param->name, param->type, loc, param->semantic, param->reg_reservation)))
|
||||
return false;
|
||||
var->is_param = 1;
|
||||
|
||||
if (param->type->type != HLSL_CLASS_OBJECT)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "hlsl.h"
|
||||
#include <stdio.h>
|
||||
#include "vkd3d_d3d9types.h"
|
||||
#include "vkd3d_d3dx9shader.h"
|
||||
|
||||
/* Split uniforms into two variables representing the constant and temp
|
||||
* registers, and copy the former to the latter, so that writes to uniforms
|
||||
@ -44,6 +44,7 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru
|
||||
list_add_tail(&ctx->extern_vars, &uniform->extern_entry);
|
||||
temp->is_uniform = 0;
|
||||
uniform->is_uniform = 1;
|
||||
uniform->is_param = temp->is_param;
|
||||
|
||||
if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers)))
|
||||
{
|
||||
@ -92,6 +93,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
|
||||
}
|
||||
vkd3d_string_buffer_release(&ctx->string_buffers, name);
|
||||
varying->is_input_varying = 1;
|
||||
varying->is_param = var->is_param;
|
||||
list_add_before(&var->scope_entry, &varying->scope_entry);
|
||||
list_add_tail(&ctx->extern_vars, &varying->extern_entry);
|
||||
|
||||
@ -170,6 +172,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
|
||||
}
|
||||
vkd3d_string_buffer_release(&ctx->string_buffers, name);
|
||||
varying->is_output_varying = 1;
|
||||
varying->is_param = var->is_param;
|
||||
list_add_before(&var->scope_entry, &varying->scope_entry);
|
||||
list_add_tail(&ctx->extern_vars, &varying->extern_entry);
|
||||
|
||||
@ -896,6 +899,34 @@ static void put_dword(struct bytecode_buffer *buffer, uint32_t value)
|
||||
buffer->data[buffer->count++] = value;
|
||||
}
|
||||
|
||||
static void set_dword(struct bytecode_buffer *buffer, unsigned int index, uint32_t value)
|
||||
{
|
||||
if (buffer->status)
|
||||
return;
|
||||
|
||||
assert(index < buffer->count);
|
||||
buffer->data[index] = value;
|
||||
}
|
||||
|
||||
static void put_string(struct bytecode_buffer *buffer, const char *str)
|
||||
{
|
||||
size_t len = strlen(str) + 1;
|
||||
unsigned int token_count = (len + 3) / sizeof(*buffer->data);
|
||||
|
||||
if (buffer->status)
|
||||
return;
|
||||
|
||||
if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->size, buffer->count + token_count, sizeof(*buffer->data)))
|
||||
{
|
||||
buffer->status = E_OUTOFMEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
buffer->data[buffer->count + token_count - 1] = 0xabababab;
|
||||
memcpy(buffer->data + buffer->count, str, len);
|
||||
buffer->count += token_count;
|
||||
}
|
||||
|
||||
static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, unsigned int minor)
|
||||
{
|
||||
if (type == VKD3D_SHADER_TYPE_VERTEX)
|
||||
@ -904,6 +935,223 @@ static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, uns
|
||||
return D3DPS_VERSION(major, minor);
|
||||
}
|
||||
|
||||
static D3DXPARAMETER_CLASS sm1_class(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->type)
|
||||
{
|
||||
case HLSL_CLASS_ARRAY:
|
||||
return sm1_class(type->e.array.type);
|
||||
case HLSL_CLASS_MATRIX:
|
||||
assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
|
||||
return D3DXPC_MATRIX_COLUMNS;
|
||||
else
|
||||
return D3DXPC_MATRIX_ROWS;
|
||||
case HLSL_CLASS_OBJECT:
|
||||
return D3DXPC_OBJECT;
|
||||
case HLSL_CLASS_SCALAR:
|
||||
return D3DXPC_SCALAR;
|
||||
case HLSL_CLASS_STRUCT:
|
||||
return D3DXPC_STRUCT;
|
||||
case HLSL_CLASS_VECTOR:
|
||||
return D3DXPC_VECTOR;
|
||||
default:
|
||||
ERR("Invalid class %#x.\n", type->type);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static D3DXPARAMETER_TYPE sm1_base_type(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->base_type)
|
||||
{
|
||||
case HLSL_TYPE_BOOL:
|
||||
return D3DXPT_BOOL;
|
||||
case HLSL_TYPE_FLOAT:
|
||||
case HLSL_TYPE_HALF:
|
||||
return D3DXPT_FLOAT;
|
||||
case HLSL_TYPE_INT:
|
||||
case HLSL_TYPE_UINT:
|
||||
return D3DXPT_INT;
|
||||
case HLSL_TYPE_PIXELSHADER:
|
||||
return D3DXPT_PIXELSHADER;
|
||||
case HLSL_TYPE_SAMPLER:
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3DXPT_SAMPLER1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3DXPT_SAMPLER2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3DXPT_SAMPLER3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3DXPT_SAMPLERCUBE;
|
||||
case HLSL_SAMPLER_DIM_GENERIC:
|
||||
return D3DXPT_SAMPLER;
|
||||
default:
|
||||
ERR("Invalid dimension %#x.\n", type->sampler_dim);
|
||||
}
|
||||
break;
|
||||
case HLSL_TYPE_STRING:
|
||||
return D3DXPT_STRING;
|
||||
case HLSL_TYPE_TEXTURE:
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3DXPT_TEXTURE1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3DXPT_TEXTURE2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3DXPT_TEXTURE3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3DXPT_TEXTURECUBE;
|
||||
case HLSL_SAMPLER_DIM_GENERIC:
|
||||
return D3DXPT_TEXTURE;
|
||||
default:
|
||||
ERR("Invalid dimension %#x.\n", type->sampler_dim);
|
||||
}
|
||||
break;
|
||||
case HLSL_TYPE_VERTEXSHADER:
|
||||
return D3DXPT_VERTEXSHADER;
|
||||
case HLSL_TYPE_VOID:
|
||||
return D3DXPT_VOID;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hlsl_type *get_array_type(const struct hlsl_type *type)
|
||||
{
|
||||
if (type->type == HLSL_CLASS_ARRAY)
|
||||
return get_array_type(type->e.array.type);
|
||||
return type;
|
||||
}
|
||||
|
||||
static unsigned int get_array_size(const struct hlsl_type *type)
|
||||
{
|
||||
if (type->type == HLSL_CLASS_ARRAY)
|
||||
return get_array_size(type->e.array.type) * type->e.array.elements_count;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *type, unsigned int ctab_start)
|
||||
{
|
||||
const struct hlsl_type *array_type = get_array_type(type);
|
||||
unsigned int fields_offset = 0, field_count = 0;
|
||||
unsigned int array_size = get_array_size(type);
|
||||
struct hlsl_struct_field *field;
|
||||
|
||||
if (type->bytecode_offset)
|
||||
return;
|
||||
|
||||
if (array_type->type == HLSL_CLASS_STRUCT)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry)
|
||||
{
|
||||
field->name_offset = buffer->count;
|
||||
put_string(buffer, field->name);
|
||||
write_sm1_type(buffer, field->type, ctab_start);
|
||||
}
|
||||
|
||||
fields_offset = (buffer->count - ctab_start) * sizeof(*buffer->data);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry)
|
||||
{
|
||||
put_dword(buffer, (field->name_offset - ctab_start) * sizeof(*buffer->data));
|
||||
put_dword(buffer, (field->type->bytecode_offset - ctab_start) * sizeof(*buffer->data));
|
||||
++field_count;
|
||||
}
|
||||
}
|
||||
|
||||
type->bytecode_offset = buffer->count;
|
||||
put_dword(buffer, sm1_class(type) | (sm1_base_type(type) << 16));
|
||||
put_dword(buffer, type->dimy | (type->dimx << 16));
|
||||
put_dword(buffer, array_size | (field_count << 16));
|
||||
put_dword(buffer, fields_offset);
|
||||
}
|
||||
|
||||
static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer,
|
||||
struct hlsl_ir_function_decl *entry_func)
|
||||
{
|
||||
unsigned int ctab_start, vars_start;
|
||||
unsigned int uniform_count = 0;
|
||||
struct hlsl_ir_var *var;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (!var->semantic && var->reg.allocated)
|
||||
{
|
||||
++uniform_count;
|
||||
|
||||
if (var->is_param && var->is_uniform)
|
||||
{
|
||||
struct vkd3d_string_buffer *name;
|
||||
|
||||
if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers)))
|
||||
{
|
||||
buffer->status = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
vkd3d_string_buffer_printf(name, "$%s", var->name);
|
||||
vkd3d_free((char *)var->name);
|
||||
var->name = vkd3d_strdup(name->buffer);
|
||||
vkd3d_string_buffer_release(&ctx->string_buffers, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
put_dword(buffer, 0); /* COMMENT tag + size */
|
||||
put_dword(buffer, MAKEFOURCC('C','T','A','B'));
|
||||
|
||||
ctab_start = buffer->count;
|
||||
|
||||
put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* size of this header */
|
||||
put_dword(buffer, 0); /* creator */
|
||||
put_dword(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
|
||||
put_dword(buffer, uniform_count);
|
||||
put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */
|
||||
put_dword(buffer, 0); /* FIXME: flags */
|
||||
put_dword(buffer, 0); /* FIXME: target string */
|
||||
|
||||
vars_start = buffer->count;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (!var->semantic && var->reg.allocated)
|
||||
{
|
||||
put_dword(buffer, 0); /* name */
|
||||
put_dword(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16));
|
||||
put_dword(buffer, var->data_type->reg_size);
|
||||
put_dword(buffer, 0); /* type */
|
||||
put_dword(buffer, 0); /* FIXME: default value */
|
||||
}
|
||||
}
|
||||
|
||||
uniform_count = 0;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (!var->semantic && var->reg.allocated)
|
||||
{
|
||||
set_dword(buffer, vars_start + (uniform_count * 5), (buffer->count - ctab_start) * sizeof(*buffer->data));
|
||||
put_string(buffer, var->name);
|
||||
|
||||
write_sm1_type(buffer, var->data_type, ctab_start);
|
||||
set_dword(buffer, vars_start + (uniform_count * 5) + 3,
|
||||
(var->data_type->bytecode_offset - ctab_start) * sizeof(*buffer->data));
|
||||
++uniform_count;
|
||||
}
|
||||
}
|
||||
|
||||
set_dword(buffer, ctab_start + 1, (buffer->count - ctab_start) * sizeof(*buffer->data));
|
||||
put_string(buffer, vkd3d_shader_get_version(NULL, NULL));
|
||||
|
||||
set_dword(buffer, ctab_start - 2, D3DSIO_COMMENT | ((buffer->count - (ctab_start - 1)) << 16));
|
||||
}
|
||||
|
||||
static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
|
||||
struct vkd3d_shader_code *out)
|
||||
{
|
||||
@ -912,12 +1160,14 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *
|
||||
|
||||
put_dword(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
|
||||
|
||||
write_sm1_uniforms(ctx, &buffer, entry_func);
|
||||
|
||||
put_dword(&buffer, D3DSIO_END);
|
||||
|
||||
if (!(ret = buffer.status))
|
||||
{
|
||||
out->code = buffer.data;
|
||||
out->size = buffer.count * sizeof(uint32_t);
|
||||
out->size = buffer.count * sizeof(*buffer.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user