mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 02:20:11 +01:00
d3d12: Handle passthrough TCS in the case where eval is bound
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Bill Kristiansen <billkris@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14399>
This commit is contained in:
parent
224c1562c1
commit
de438f381f
9 changed files with 246 additions and 14 deletions
|
|
@ -354,7 +354,7 @@ fill_mode_lowered(struct d3d12_context *ctx, const struct pipe_draw_info *dinfo)
|
|||
struct d3d12_shader_selector *vs = ctx->gfx_stages[PIPE_SHADER_VERTEX];
|
||||
|
||||
if ((ctx->gfx_stages[PIPE_SHADER_GEOMETRY] != NULL &&
|
||||
!ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->is_gs_variant) ||
|
||||
!ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->is_variant) ||
|
||||
ctx->gfx_pipeline_state.rast == NULL ||
|
||||
(dinfo->mode != PIPE_PRIM_TRIANGLES &&
|
||||
dinfo->mode != PIPE_PRIM_TRIANGLE_STRIP))
|
||||
|
|
@ -394,7 +394,7 @@ needs_point_sprite_lowering(struct d3d12_context *ctx, const struct pipe_draw_in
|
|||
struct d3d12_shader_selector *vs = ctx->gfx_stages[PIPE_SHADER_VERTEX];
|
||||
struct d3d12_shader_selector *gs = ctx->gfx_stages[PIPE_SHADER_GEOMETRY];
|
||||
|
||||
if (gs != NULL && !gs->is_gs_variant) {
|
||||
if (gs != NULL && !gs->is_variant) {
|
||||
/* There is an user GS; Check if it outputs points with PSIZE */
|
||||
return (gs->initial->info.gs.output_primitive == GL_POINTS &&
|
||||
(gs->initial->info.outputs_written & VARYING_BIT_PSIZ ||
|
||||
|
|
@ -417,7 +417,7 @@ static unsigned
|
|||
cull_mode_lowered(struct d3d12_context *ctx, unsigned fill_mode)
|
||||
{
|
||||
if ((ctx->gfx_stages[PIPE_SHADER_GEOMETRY] != NULL &&
|
||||
!ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->is_gs_variant) ||
|
||||
!ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->is_variant) ||
|
||||
ctx->gfx_pipeline_state.rast == NULL ||
|
||||
ctx->gfx_pipeline_state.rast->base.cull_face == PIPE_FACE_NONE)
|
||||
return PIPE_FACE_NONE;
|
||||
|
|
@ -435,7 +435,7 @@ get_provoking_vertex(struct d3d12_selection_context *sel_ctx, bool *alternate, c
|
|||
|
||||
struct d3d12_shader_selector *vs = sel_ctx->ctx->gfx_stages[PIPE_SHADER_VERTEX];
|
||||
struct d3d12_shader_selector *gs = sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY];
|
||||
struct d3d12_shader_selector *last_vertex_stage = gs && !gs->is_gs_variant ? gs : vs;
|
||||
struct d3d12_shader_selector *last_vertex_stage = gs && !gs->is_variant ? gs : vs;
|
||||
|
||||
/* Make sure GL prims match Gallium prims */
|
||||
STATIC_ASSERT(GL_POINTS == PIPE_PRIM_POINTS);
|
||||
|
|
@ -457,7 +457,7 @@ get_provoking_vertex(struct d3d12_selection_context *sel_ctx, bool *alternate, c
|
|||
bool flatshade_first = sel_ctx->ctx->gfx_pipeline_state.rast &&
|
||||
sel_ctx->ctx->gfx_pipeline_state.rast->base.flatshade_first;
|
||||
*alternate = (mode == GL_TRIANGLE_STRIP || mode == GL_TRIANGLE_STRIP_ADJACENCY) &&
|
||||
(!gs || gs->is_gs_variant ||
|
||||
(!gs || gs->is_variant ||
|
||||
gs->initial->info.gs.vertices_out > u_prim_vertex_count(mode)->min);
|
||||
return flatshade_first ? 0 : u_prim_vertex_count(mode)->min - 1;
|
||||
}
|
||||
|
|
@ -580,7 +580,7 @@ validate_geometry_shader_variant(struct d3d12_selection_context *sel_ctx)
|
|||
d3d12_shader_selector *gs = ctx->gfx_stages[PIPE_SHADER_GEOMETRY];
|
||||
|
||||
/* Nothing to do if there is a user geometry shader bound */
|
||||
if (gs != NULL && !gs->is_gs_variant)
|
||||
if (gs != NULL && !gs->is_variant)
|
||||
return;
|
||||
|
||||
/* Fill the geometry shader variant key */
|
||||
|
|
@ -619,6 +619,37 @@ validate_geometry_shader_variant(struct d3d12_selection_context *sel_ctx)
|
|||
ctx->gfx_stages[PIPE_SHADER_GEOMETRY] = gs;
|
||||
}
|
||||
|
||||
static void
|
||||
validate_tess_ctrl_shader_variant(struct d3d12_selection_context *sel_ctx)
|
||||
{
|
||||
struct d3d12_context *ctx = sel_ctx->ctx;
|
||||
d3d12_shader_selector *vs = ctx->gfx_stages[PIPE_SHADER_VERTEX];
|
||||
d3d12_shader_selector *tcs = ctx->gfx_stages[PIPE_SHADER_TESS_CTRL];
|
||||
d3d12_shader_selector *tes = ctx->gfx_stages[PIPE_SHADER_TESS_EVAL];
|
||||
struct d3d12_tcs_variant_key key = {0};
|
||||
|
||||
/* Nothing to do if there is a user tess ctrl shader bound */
|
||||
if (tcs != NULL && !tcs->is_variant)
|
||||
return;
|
||||
|
||||
bool variant_needed = tes != nullptr;
|
||||
|
||||
/* Fill the variant key */
|
||||
if (variant_needed) {
|
||||
fill_varyings(&key.varyings, vs->initial, nir_var_shader_out,
|
||||
vs->initial->info.outputs_written, false);
|
||||
key.vertices_out = ctx->patch_vertices;
|
||||
}
|
||||
|
||||
/* Check if the currently bound tessellation control shader variant is correct */
|
||||
if (tcs && memcmp(&tcs->tcs_key, &key, sizeof(key)) == 0)
|
||||
return;
|
||||
|
||||
/* Find/create the proper variant and bind it */
|
||||
tcs = variant_needed ? d3d12_get_tcs_variant(ctx, &key) : NULL;
|
||||
ctx->gfx_stages[PIPE_SHADER_TESS_CTRL] = tcs;
|
||||
}
|
||||
|
||||
static bool
|
||||
d3d12_compare_shader_keys(const d3d12_shader_key *expect, const d3d12_shader_key *have)
|
||||
{
|
||||
|
|
@ -779,7 +810,7 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
|
|||
/* We require as outputs what the next stage reads,
|
||||
* except certain system values */
|
||||
if (next) {
|
||||
if (!next->is_gs_variant) {
|
||||
if (!next->is_variant) {
|
||||
if (stage == PIPE_SHADER_VERTEX)
|
||||
system_generated_in_values |= VARYING_BIT_POS;
|
||||
uint64_t mask = next->current->nir->info.inputs_read & ~system_generated_in_values;
|
||||
|
|
@ -819,11 +850,11 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
|
|||
key->gs.stream_output_factor = 6;
|
||||
} else if (sel_ctx->fill_mode_lowered == PIPE_POLYGON_MODE_LINE) {
|
||||
key->gs.stream_output_factor = 2;
|
||||
} else if (sel_ctx->needs_vertex_reordering && !sel->is_gs_variant) {
|
||||
} else if (sel_ctx->needs_vertex_reordering && !sel->is_variant) {
|
||||
key->gs.triangle_strip = 1;
|
||||
}
|
||||
|
||||
if (sel->is_gs_variant && next && next->initial->info.inputs_read & VARYING_BIT_PRIMITIVE_ID)
|
||||
if (sel->is_variant && next && next->initial->info.inputs_read & VARYING_BIT_PRIMITIVE_ID)
|
||||
key->gs.primitive_id = 1;
|
||||
} else if (stage == PIPE_SHADER_FRAGMENT) {
|
||||
key->fs.missing_dual_src_outputs = sel_ctx->missing_dual_src_outputs;
|
||||
|
|
@ -901,7 +932,7 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
|
|||
|
||||
if (stage == PIPE_SHADER_FRAGMENT &&
|
||||
sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY] &&
|
||||
sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->is_gs_variant &&
|
||||
sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->is_variant &&
|
||||
sel_ctx->ctx->gfx_stages[PIPE_SHADER_GEOMETRY]->gs_key.has_front_face) {
|
||||
key->fs.remap_front_facing = 1;
|
||||
}
|
||||
|
|
@ -1338,6 +1369,7 @@ d3d12_select_shader_variants(struct d3d12_context *ctx, const struct pipe_draw_i
|
|||
sel_ctx.manual_depth_range = manual_depth_range(ctx);
|
||||
|
||||
validate_geometry_shader_variant(&sel_ctx);
|
||||
validate_tess_ctrl_shader_variant(&sel_ctx);
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(order); ++i) {
|
||||
auto sel = ctx->gfx_stages[order[i]];
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ enum d3d12_state_var {
|
|||
D3D12_STATE_VAR_PT_SPRITE,
|
||||
D3D12_STATE_VAR_DRAW_PARAMS,
|
||||
D3D12_STATE_VAR_DEPTH_TRANSFORM,
|
||||
D3D12_STATE_VAR_DEFAULT_INNER_TESS_LEVEL,
|
||||
D3D12_STATE_VAR_DEFAULT_OUTER_TESS_LEVEL,
|
||||
D3D12_MAX_GRAPHICS_STATE_VARS,
|
||||
|
||||
D3D12_STATE_VAR_NUM_WORKGROUPS = 0,
|
||||
|
|
@ -203,6 +205,12 @@ struct d3d12_gs_variant_key
|
|||
struct d3d12_varying_info varyings;
|
||||
};
|
||||
|
||||
struct d3d12_tcs_variant_key
|
||||
{
|
||||
unsigned vertices_out;
|
||||
struct d3d12_varying_info varyings;
|
||||
};
|
||||
|
||||
struct d3d12_shader_selector {
|
||||
enum pipe_shader_type stage;
|
||||
nir_shader *initial;
|
||||
|
|
@ -215,8 +223,11 @@ struct d3d12_shader_selector {
|
|||
unsigned compare_with_lod_bias_grad:1;
|
||||
unsigned workgroup_size_variable:1;
|
||||
|
||||
bool is_gs_variant;
|
||||
bool is_variant;
|
||||
union {
|
||||
struct d3d12_gs_variant_key gs_key;
|
||||
struct d3d12_tcs_variant_key tcs_key;
|
||||
};
|
||||
};
|
||||
|
||||
struct d3d12_context;
|
||||
|
|
@ -250,6 +261,15 @@ d3d12_gs_variant_cache_destroy(struct d3d12_context *ctx);
|
|||
struct d3d12_shader_selector *
|
||||
d3d12_get_gs_variant(struct d3d12_context *ctx, struct d3d12_gs_variant_key *key);
|
||||
|
||||
void
|
||||
d3d12_tcs_variant_cache_init(struct d3d12_context *ctx);
|
||||
|
||||
void
|
||||
d3d12_tcs_variant_cache_destroy(struct d3d12_context *ctx);
|
||||
|
||||
struct d3d12_shader_selector *
|
||||
d3d12_get_tcs_variant(struct d3d12_context *ctx, struct d3d12_tcs_variant_key *key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2272,6 +2272,16 @@ d3d12_set_patch_vertices(struct pipe_context *pctx, uint8_t patch_vertices)
|
|||
ctx->cmdlist_dirty |= D3D12_DIRTY_PRIM_MODE;
|
||||
}
|
||||
|
||||
static void
|
||||
d3d12_set_tess_state(struct pipe_context *pctx,
|
||||
const float default_outer_level[4],
|
||||
const float default_inner_level[2])
|
||||
{
|
||||
struct d3d12_context *ctx = d3d12_context(pctx);
|
||||
memcpy(ctx->default_outer_tess_factor, default_outer_level, sizeof(ctx->default_outer_tess_factor));
|
||||
memcpy(ctx->default_inner_tess_factor, default_inner_level, sizeof(ctx->default_inner_tess_factor));
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||
{
|
||||
|
|
@ -2331,6 +2341,7 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
|||
ctx->base.delete_tes_state = d3d12_delete_tes_state;
|
||||
|
||||
ctx->base.set_patch_vertices = d3d12_set_patch_vertices;
|
||||
ctx->base.set_tess_state = d3d12_set_tess_state;
|
||||
|
||||
ctx->base.create_compute_state = d3d12_create_compute_state;
|
||||
ctx->base.bind_compute_state = d3d12_bind_compute_state;
|
||||
|
|
@ -2404,6 +2415,7 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
|||
d3d12_root_signature_cache_init(ctx);
|
||||
d3d12_cmd_signature_cache_init(ctx);
|
||||
d3d12_gs_variant_cache_init(ctx);
|
||||
d3d12_tcs_variant_cache_init(ctx);
|
||||
d3d12_compute_transform_cache_init(ctx);
|
||||
|
||||
util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT);
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ struct d3d12_context {
|
|||
struct hash_table *root_signature_cache;
|
||||
struct hash_table *cmd_signature_cache;
|
||||
struct hash_table *gs_variant_cache;
|
||||
struct hash_table *tcs_variant_cache;
|
||||
struct hash_table *compute_transform_cache;
|
||||
|
||||
struct d3d12_batch batches[4];
|
||||
|
|
@ -222,6 +223,8 @@ struct d3d12_context {
|
|||
D3D12_STREAM_OUTPUT_BUFFER_VIEW fake_so_buffer_views[PIPE_MAX_SO_BUFFERS];
|
||||
unsigned fake_so_buffer_factor;
|
||||
uint8_t patch_vertices;
|
||||
float default_outer_tess_factor[4];
|
||||
float default_inner_tess_factor[2];
|
||||
|
||||
struct d3d12_shader_selector *gfx_stages[D3D12_GFX_SHADER_STAGES];
|
||||
struct d3d12_shader_selector *compute_state;
|
||||
|
|
|
|||
|
|
@ -380,6 +380,14 @@ fill_graphics_state_vars(struct d3d12_context *ctx,
|
|||
ptr[1] = fui(ctx->viewport_states[0].translate[2] - ctx->viewport_states[0].scale[2]);
|
||||
size += 4;
|
||||
break;
|
||||
case D3D12_STATE_VAR_DEFAULT_INNER_TESS_LEVEL:
|
||||
memcpy(ptr, ctx->default_inner_tess_factor, sizeof(ctx->default_inner_tess_factor));
|
||||
size += 4;
|
||||
break;
|
||||
case D3D12_STATE_VAR_DEFAULT_OUTER_TESS_LEVEL:
|
||||
memcpy(ptr, ctx->default_outer_tess_factor, sizeof(ctx->default_outer_tess_factor));
|
||||
size += 4;
|
||||
break;
|
||||
default:
|
||||
unreachable("unknown state variable");
|
||||
}
|
||||
|
|
@ -706,7 +714,7 @@ static inline struct d3d12_shader_selector *
|
|||
d3d12_last_vertex_stage(struct d3d12_context *ctx)
|
||||
{
|
||||
struct d3d12_shader_selector *sel = ctx->gfx_stages[PIPE_SHADER_GEOMETRY];
|
||||
if (!sel || sel->is_gs_variant)
|
||||
if (!sel || sel->is_variant)
|
||||
sel = ctx->gfx_stages[PIPE_SHADER_TESS_EVAL];
|
||||
if (!sel)
|
||||
sel = ctx->gfx_stages[PIPE_SHADER_VERTEX];
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ create_geometry_shader_variant(struct d3d12_context *ctx, struct d3d12_gs_varian
|
|||
gs = d3d12_emit_lines(ctx, key);
|
||||
|
||||
if (gs) {
|
||||
gs->is_gs_variant = true;
|
||||
gs->is_variant = true;
|
||||
gs->gs_key = *key;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,13 @@ struct d3d12_shader;
|
|||
struct d3d12_image_format_conversion_info;
|
||||
enum d3d12_state_var;
|
||||
|
||||
nir_ssa_def *
|
||||
d3d12_get_state_var(nir_builder *b,
|
||||
enum d3d12_state_var var_enum,
|
||||
const char *var_name,
|
||||
const struct glsl_type *var_type,
|
||||
nir_variable **out_var);
|
||||
|
||||
nir_ssa_def *
|
||||
d3d12_get_state_var(nir_builder *b,
|
||||
enum d3d12_state_var var_enum,
|
||||
|
|
|
|||
149
src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp
Normal file
149
src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
#include "d3d12_context.h"
|
||||
#include "d3d12_compiler.h"
|
||||
#include "d3d12_nir_passes.h"
|
||||
#include "nir_to_dxil.h"
|
||||
|
||||
static uint32_t
|
||||
hash_tcs_variant_key(const void *key)
|
||||
{
|
||||
return _mesa_hash_data(key, sizeof(struct d3d12_tcs_variant_key));
|
||||
}
|
||||
|
||||
static bool
|
||||
equals_tcs_variant_key(const void *a, const void *b)
|
||||
{
|
||||
return memcmp(a, b, sizeof(struct d3d12_tcs_variant_key)) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_tcs_variant_cache_init(struct d3d12_context *ctx)
|
||||
{
|
||||
ctx->tcs_variant_cache = _mesa_hash_table_create(NULL, NULL, equals_tcs_variant_key);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_entry(struct hash_entry *entry)
|
||||
{
|
||||
d3d12_shader_free((d3d12_shader_selector *)entry->data);
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_tcs_variant_cache_destroy(struct d3d12_context *ctx)
|
||||
{
|
||||
_mesa_hash_table_destroy(ctx->tcs_variant_cache, delete_entry);
|
||||
}
|
||||
|
||||
static struct d3d12_shader_selector *
|
||||
create_tess_ctrl_shader_variant(struct d3d12_context *ctx, struct d3d12_tcs_variant_key *key)
|
||||
{
|
||||
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_TESS_CTRL, dxil_get_nir_compiler_options(), "passthrough");
|
||||
nir_shader *nir = b.shader;
|
||||
|
||||
nir_ssa_def *invocation_id = nir_load_invocation_id(&b);
|
||||
uint64_t varying_mask = key->varyings.mask;
|
||||
|
||||
while(varying_mask) {
|
||||
int var_idx = u_bit_scan64(&varying_mask);
|
||||
auto var = &key->varyings.vars[var_idx];
|
||||
const struct glsl_type *type = var->type;
|
||||
const struct glsl_type *in_type = var->type;
|
||||
const struct glsl_type *out_type = var->type;
|
||||
in_type = glsl_array_type(type, key->vertices_out, 0);
|
||||
out_type = glsl_array_type(type, key->vertices_out, 0);
|
||||
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "in_%d", var->driver_location);
|
||||
nir_variable *in = nir_variable_create(nir, nir_var_shader_in, in_type, buf);
|
||||
snprintf(buf, sizeof(buf), "out_%d", var->driver_location);
|
||||
nir_variable *out = nir_variable_create(nir, nir_var_shader_out, out_type, buf);
|
||||
out->data.location = in->data.location = var_idx;
|
||||
out->data.driver_location = in->data.driver_location = var->driver_location;
|
||||
|
||||
for (unsigned i = 0; i < key->vertices_out; i++) {
|
||||
nir_if *start_block = nir_push_if(&b, nir_ieq(&b, invocation_id, nir_imm_int(&b, i)));
|
||||
nir_deref_instr *in_array_var = nir_build_deref_array(&b, nir_build_deref_var(&b, in), invocation_id);
|
||||
nir_ssa_def *load = nir_load_deref(&b, in_array_var);
|
||||
nir_deref_instr *out_array_var = nir_build_deref_array_imm(&b, nir_build_deref_var(&b, out), i);
|
||||
nir_store_deref(&b, out_array_var, load, 0xff);
|
||||
nir_pop_if(&b, start_block);
|
||||
}
|
||||
}
|
||||
nir_variable *gl_TessLevelInner = nir_variable_create(nir, nir_var_shader_out, glsl_array_type(glsl_float_type(), 2, 0), "gl_TessLevelInner");
|
||||
gl_TessLevelInner->data.location = VARYING_SLOT_TESS_LEVEL_INNER;
|
||||
gl_TessLevelInner->data.patch = 1;
|
||||
gl_TessLevelInner->data.compact = 1;
|
||||
nir_variable *gl_TessLevelOuter = nir_variable_create(nir, nir_var_shader_out, glsl_array_type(glsl_float_type(), 4, 0), "gl_TessLevelOuter");
|
||||
gl_TessLevelOuter->data.location = VARYING_SLOT_TESS_LEVEL_OUTER;
|
||||
gl_TessLevelOuter->data.patch = 1;
|
||||
gl_TessLevelOuter->data.compact = 1;
|
||||
|
||||
nir_variable *state_var_inner = NULL, *state_var_outer = NULL;
|
||||
nir_ssa_def *load_inner = d3d12_get_state_var(&b, D3D12_STATE_VAR_DEFAULT_INNER_TESS_LEVEL, "d3d12_TessLevelInner", glsl_vec_type(2), &state_var_inner);
|
||||
nir_ssa_def *load_outer = d3d12_get_state_var(&b, D3D12_STATE_VAR_DEFAULT_OUTER_TESS_LEVEL, "d3d12_TessLevelOuter", glsl_vec4_type(), &state_var_outer);
|
||||
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
nir_deref_instr *store_idx = nir_build_deref_array_imm(&b, nir_build_deref_var(&b, gl_TessLevelInner), i);
|
||||
nir_store_deref(&b, store_idx, nir_channel(&b, load_inner, i), 0xff);
|
||||
}
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
nir_deref_instr *store_idx = nir_build_deref_array_imm(&b, nir_build_deref_var(&b, gl_TessLevelOuter), i);
|
||||
nir_store_deref(&b, store_idx, nir_channel(&b, load_outer, i), 0xff);
|
||||
}
|
||||
|
||||
nir->info.tess.tcs_vertices_out = key->vertices_out;
|
||||
nir_validate_shader(nir, "created");
|
||||
|
||||
struct pipe_shader_state templ;
|
||||
|
||||
templ.type = PIPE_SHADER_IR_NIR;
|
||||
templ.ir.nir = nir;
|
||||
templ.stream_output.num_outputs = 0;
|
||||
|
||||
d3d12_shader_selector *tcs = d3d12_create_shader(ctx, PIPE_SHADER_TESS_CTRL, &templ);
|
||||
if (tcs) {
|
||||
tcs->is_variant = true;
|
||||
memcpy(&tcs->tcs_key, key, sizeof(*key));
|
||||
}
|
||||
return tcs;
|
||||
}
|
||||
|
||||
d3d12_shader_selector *
|
||||
d3d12_get_tcs_variant(struct d3d12_context *ctx, struct d3d12_tcs_variant_key *key)
|
||||
{
|
||||
uint32_t hash = hash_tcs_variant_key(key);
|
||||
struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ctx->tcs_variant_cache,
|
||||
hash, key);
|
||||
if (!entry) {
|
||||
d3d12_shader_selector *tcs = create_tess_ctrl_shader_variant(ctx, key);
|
||||
entry = _mesa_hash_table_insert_pre_hashed(ctx->tcs_variant_cache,
|
||||
hash, &tcs->tcs_key, tcs);
|
||||
assert(entry);
|
||||
}
|
||||
|
||||
return (d3d12_shader_selector *)entry->data;
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@ files_libd3d12 = files(
|
|||
'd3d12_root_signature.cpp',
|
||||
'd3d12_screen.cpp',
|
||||
'd3d12_surface.cpp',
|
||||
'd3d12_tcs_variant.cpp',
|
||||
)
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue