mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/fx: Initial support for fx_5_0 output.
This commit is contained in:
parent
8014c11e88
commit
e7d65d39ba
Notes:
Alexandre Julliard
2024-01-15 23:02:43 +01:00
Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/560
@ -25,10 +25,47 @@ struct fx_write_context
|
||||
struct vkd3d_bytecode_buffer unstructured;
|
||||
struct vkd3d_bytecode_buffer structured;
|
||||
|
||||
unsigned int min_technique_version;
|
||||
unsigned int max_technique_version;
|
||||
|
||||
uint32_t technique_count;
|
||||
uint32_t group_count;
|
||||
int status;
|
||||
};
|
||||
|
||||
static void fx_write_context_init(const struct hlsl_ctx *ctx, struct fx_write_context *fx)
|
||||
{
|
||||
unsigned int version = ctx->profile->major_version;
|
||||
|
||||
memset(fx, 0, sizeof(*fx));
|
||||
|
||||
if (version == 2)
|
||||
{
|
||||
fx->min_technique_version = 9;
|
||||
fx->max_technique_version = 9;
|
||||
}
|
||||
else if (version == 4)
|
||||
{
|
||||
fx->min_technique_version = 10;
|
||||
fx->max_technique_version = 10;
|
||||
}
|
||||
else if (version == 5)
|
||||
{
|
||||
fx->min_technique_version = 10;
|
||||
fx->max_technique_version = 11;
|
||||
}
|
||||
}
|
||||
|
||||
static bool technique_matches_version(const struct hlsl_ir_var *var, const struct fx_write_context *fx)
|
||||
{
|
||||
const struct hlsl_type *type = var->data_type;
|
||||
|
||||
if (type->base_type != HLSL_TYPE_TECHNIQUE)
|
||||
return false;
|
||||
|
||||
return type->e.version >= fx->min_technique_version && type->e.version <= fx->max_technique_version;
|
||||
}
|
||||
|
||||
static uint32_t fx_put_raw_string(struct fx_write_context *fx, const char *string)
|
||||
{
|
||||
/* NULLs are emitted as empty strings using the same 4 bytes at the start of the section. */
|
||||
@ -94,13 +131,55 @@ static void write_techniques(struct hlsl_scope *scope, struct fx_write_context *
|
||||
set_status(fx, fx->structured.status);
|
||||
}
|
||||
|
||||
static void write_group(struct hlsl_scope *scope, const char *name, struct fx_write_context *fx)
|
||||
{
|
||||
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
|
||||
uint32_t name_offset = fx_put_raw_string(fx, name);
|
||||
uint32_t count_offset, count;
|
||||
|
||||
put_u32(buffer, name_offset);
|
||||
count_offset = put_u32(buffer, 0); /* Technique count */
|
||||
put_u32(buffer, 0); /* Annotation count */
|
||||
|
||||
count = fx->technique_count;
|
||||
write_techniques(scope, fx);
|
||||
set_u32(buffer, count_offset, fx->technique_count - count);
|
||||
|
||||
++fx->group_count;
|
||||
}
|
||||
|
||||
static void write_groups(struct hlsl_scope *scope, struct fx_write_context *fx)
|
||||
{
|
||||
bool needs_default_group = false;
|
||||
struct hlsl_ir_var *var;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
|
||||
{
|
||||
if (technique_matches_version(var, fx))
|
||||
{
|
||||
needs_default_group = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_default_group)
|
||||
write_group(scope, NULL, fx);
|
||||
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
|
||||
{
|
||||
const struct hlsl_type *type = var->data_type;
|
||||
|
||||
if (type->base_type == HLSL_TYPE_EFFECT_GROUP)
|
||||
write_group(var->scope, var->name, fx);
|
||||
}
|
||||
}
|
||||
|
||||
static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
||||
{
|
||||
struct vkd3d_bytecode_buffer buffer = { 0 };
|
||||
struct fx_write_context fx;
|
||||
uint32_t size_offset, size;
|
||||
|
||||
memset(&fx, 0, sizeof(fx));
|
||||
fx_write_context_init(ctx, &fx);
|
||||
|
||||
put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
|
||||
|
||||
@ -154,6 +233,70 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
||||
return fx.status;
|
||||
}
|
||||
|
||||
static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
||||
{
|
||||
struct vkd3d_bytecode_buffer buffer = { 0 };
|
||||
struct fx_write_context fx;
|
||||
uint32_t size_offset, size;
|
||||
|
||||
fx_write_context_init(ctx, &fx);
|
||||
|
||||
put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
|
||||
|
||||
/* TODO: buffers */
|
||||
/* TODO: objects */
|
||||
/* TODO: interface variables */
|
||||
|
||||
write_groups(ctx->globals, &fx);
|
||||
|
||||
put_u32(&buffer, 0xfeff2001); /* Version. */
|
||||
put_u32(&buffer, 0); /* Buffer count. */
|
||||
put_u32(&buffer, 0); /* Variable count. */
|
||||
put_u32(&buffer, 0); /* Object count. */
|
||||
put_u32(&buffer, 0); /* Pool buffer count. */
|
||||
put_u32(&buffer, 0); /* Pool variable count. */
|
||||
put_u32(&buffer, 0); /* Pool object count. */
|
||||
put_u32(&buffer, fx.technique_count);
|
||||
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
|
||||
put_u32(&buffer, 0); /* String count. */
|
||||
put_u32(&buffer, 0); /* Texture object count. */
|
||||
put_u32(&buffer, 0); /* Depth stencil state count. */
|
||||
put_u32(&buffer, 0); /* Blend state count. */
|
||||
put_u32(&buffer, 0); /* Rasterizer state count. */
|
||||
put_u32(&buffer, 0); /* Sampler state count. */
|
||||
put_u32(&buffer, 0); /* Rendertarget view count. */
|
||||
put_u32(&buffer, 0); /* Depth stencil view count. */
|
||||
put_u32(&buffer, 0); /* Shader count. */
|
||||
put_u32(&buffer, 0); /* Inline shader count. */
|
||||
put_u32(&buffer, fx.group_count); /* Group count. */
|
||||
put_u32(&buffer, 0); /* UAV count. */
|
||||
put_u32(&buffer, 0); /* Interface variables count. */
|
||||
put_u32(&buffer, 0); /* Interface variable element count. */
|
||||
put_u32(&buffer, 0); /* Class instance elements count. */
|
||||
|
||||
size = align(fx.unstructured.size, 4);
|
||||
set_u32(&buffer, size_offset, size);
|
||||
|
||||
bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size);
|
||||
bytecode_put_bytes(&buffer, fx.structured.data, fx.structured.size);
|
||||
|
||||
vkd3d_free(fx.unstructured.data);
|
||||
vkd3d_free(fx.structured.data);
|
||||
|
||||
set_status(&fx, buffer.status);
|
||||
|
||||
if (!fx.status)
|
||||
{
|
||||
out->code = buffer.data;
|
||||
out->size = buffer.size;
|
||||
}
|
||||
|
||||
if (fx.status < 0)
|
||||
ctx->result = fx.status;
|
||||
|
||||
return fx.status;
|
||||
}
|
||||
|
||||
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
||||
{
|
||||
if (ctx->profile->major_version == 2)
|
||||
@ -167,8 +310,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
||||
}
|
||||
else if (ctx->profile->major_version == 5)
|
||||
{
|
||||
hlsl_fixme(ctx, &ctx->location, "Writing fx_5_0 binaries is not implemented.");
|
||||
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||
return hlsl_fx_5_write(ctx, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ float4 main() : sv_target
|
||||
return fxGroup;
|
||||
}
|
||||
|
||||
[effect todo]
|
||||
[effect]
|
||||
technique
|
||||
{
|
||||
}
|
||||
@ -47,11 +47,11 @@ technique10
|
||||
}
|
||||
|
||||
% Effects without techniques are allowed for fx_5_0
|
||||
[effect todo]
|
||||
[effect]
|
||||
float4 f;
|
||||
|
||||
% fx_2_0 keyword is allowed with fx_5_0 profiles
|
||||
[effect todo]
|
||||
[effect]
|
||||
technique
|
||||
{
|
||||
}
|
||||
@ -90,10 +90,10 @@ float4 technique10;
|
||||
[effect fail]
|
||||
float4 technique11;
|
||||
|
||||
[effect todo]
|
||||
[effect]
|
||||
float4 technIque10;
|
||||
|
||||
[effect todo]
|
||||
[effect]
|
||||
float4 technIque11;
|
||||
|
||||
% Regular shaders with technique blocks
|
||||
@ -174,7 +174,7 @@ fxgroup group
|
||||
}
|
||||
|
||||
% Group provides scope for techniques
|
||||
[effect todo]
|
||||
[effect]
|
||||
fxgroup group1
|
||||
{
|
||||
technique11 tech0 {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user