mesa/st: add support for ARB_sample_shading
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
@@ -120,6 +120,7 @@ struct cso_context {
|
|||||||
struct pipe_viewport_state vp, vp_saved;
|
struct pipe_viewport_state vp, vp_saved;
|
||||||
struct pipe_blend_color blend_color;
|
struct pipe_blend_color blend_color;
|
||||||
unsigned sample_mask, sample_mask_saved;
|
unsigned sample_mask, sample_mask_saved;
|
||||||
|
unsigned min_samples, min_samples_saved;
|
||||||
struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
|
struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -716,6 +717,24 @@ void cso_restore_sample_mask(struct cso_context *ctx)
|
|||||||
cso_set_sample_mask(ctx, ctx->sample_mask_saved);
|
cso_set_sample_mask(ctx, ctx->sample_mask_saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cso_set_min_samples(struct cso_context *ctx, unsigned min_samples)
|
||||||
|
{
|
||||||
|
if (ctx->min_samples != min_samples && ctx->pipe->set_min_samples) {
|
||||||
|
ctx->min_samples = min_samples;
|
||||||
|
ctx->pipe->set_min_samples(ctx->pipe, min_samples);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cso_save_min_samples(struct cso_context *ctx)
|
||||||
|
{
|
||||||
|
ctx->min_samples_saved = ctx->min_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cso_restore_min_samples(struct cso_context *ctx)
|
||||||
|
{
|
||||||
|
cso_set_min_samples(ctx, ctx->min_samples_saved);
|
||||||
|
}
|
||||||
|
|
||||||
void cso_set_stencil_ref(struct cso_context *ctx,
|
void cso_set_stencil_ref(struct cso_context *ctx,
|
||||||
const struct pipe_stencil_ref *sr)
|
const struct pipe_stencil_ref *sr)
|
||||||
{
|
{
|
||||||
|
@@ -164,6 +164,10 @@ void cso_set_sample_mask(struct cso_context *cso, unsigned stencil_mask);
|
|||||||
void cso_save_sample_mask(struct cso_context *ctx);
|
void cso_save_sample_mask(struct cso_context *ctx);
|
||||||
void cso_restore_sample_mask(struct cso_context *ctx);
|
void cso_restore_sample_mask(struct cso_context *ctx);
|
||||||
|
|
||||||
|
void cso_set_min_samples(struct cso_context *cso, unsigned min_samples);
|
||||||
|
void cso_save_min_samples(struct cso_context *ctx);
|
||||||
|
void cso_restore_min_samples(struct cso_context *ctx);
|
||||||
|
|
||||||
void cso_set_stencil_ref(struct cso_context *cso,
|
void cso_set_stencil_ref(struct cso_context *cso,
|
||||||
const struct pipe_stencil_ref *sr);
|
const struct pipe_stencil_ref *sr);
|
||||||
void cso_save_stencil_ref(struct cso_context *cso);
|
void cso_save_stencil_ref(struct cso_context *cso);
|
||||||
|
@@ -412,6 +412,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
|
|||||||
|
|
||||||
cso_save_framebuffer(cso);
|
cso_save_framebuffer(cso);
|
||||||
cso_save_sample_mask(cso);
|
cso_save_sample_mask(cso);
|
||||||
|
cso_save_min_samples(cso);
|
||||||
cso_save_blend(cso);
|
cso_save_blend(cso);
|
||||||
cso_save_depth_stencil_alpha(cso);
|
cso_save_depth_stencil_alpha(cso);
|
||||||
cso_save_fragment_shader(cso);
|
cso_save_fragment_shader(cso);
|
||||||
@@ -450,6 +451,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
|
|||||||
|
|
||||||
cso_set_framebuffer(cso, &fb);
|
cso_set_framebuffer(cso, &fb);
|
||||||
cso_set_sample_mask(cso, ~0);
|
cso_set_sample_mask(cso, ~0);
|
||||||
|
cso_set_min_samples(cso, 1);
|
||||||
cso_set_blend(cso, &hud->alpha_blend);
|
cso_set_blend(cso, &hud->alpha_blend);
|
||||||
cso_set_depth_stencil_alpha(cso, &hud->dsa);
|
cso_set_depth_stencil_alpha(cso, &hud->dsa);
|
||||||
cso_set_rasterizer(cso, &hud->rasterizer);
|
cso_set_rasterizer(cso, &hud->rasterizer);
|
||||||
@@ -538,6 +540,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
|
|||||||
/* restore states */
|
/* restore states */
|
||||||
cso_restore_framebuffer(cso);
|
cso_restore_framebuffer(cso);
|
||||||
cso_restore_sample_mask(cso);
|
cso_restore_sample_mask(cso);
|
||||||
|
cso_restore_min_samples(cso);
|
||||||
cso_restore_blend(cso);
|
cso_restore_blend(cso);
|
||||||
cso_restore_depth_stencil_alpha(cso);
|
cso_restore_depth_stencil_alpha(cso);
|
||||||
cso_restore_fragment_shader(cso);
|
cso_restore_fragment_shader(cso);
|
||||||
|
@@ -122,6 +122,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||||||
cso_save_geometry_shader(cso);
|
cso_save_geometry_shader(cso);
|
||||||
cso_save_rasterizer(cso);
|
cso_save_rasterizer(cso);
|
||||||
cso_save_sample_mask(cso);
|
cso_save_sample_mask(cso);
|
||||||
|
cso_save_min_samples(cso);
|
||||||
cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
|
cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
|
cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_save_stencil_ref(cso);
|
cso_save_stencil_ref(cso);
|
||||||
@@ -136,6 +137,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||||||
|
|
||||||
/* set default state */
|
/* set default state */
|
||||||
cso_set_sample_mask(cso, ~0);
|
cso_set_sample_mask(cso, ~0);
|
||||||
|
cso_set_min_samples(cso, 1);
|
||||||
cso_set_stream_outputs(cso, 0, NULL, NULL);
|
cso_set_stream_outputs(cso, 0, NULL, NULL);
|
||||||
cso_set_geometry_shader_handle(cso, NULL);
|
cso_set_geometry_shader_handle(cso, NULL);
|
||||||
cso_set_render_condition(cso, NULL, FALSE, 0);
|
cso_set_render_condition(cso, NULL, FALSE, 0);
|
||||||
@@ -187,6 +189,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||||||
cso_restore_geometry_shader(cso);
|
cso_restore_geometry_shader(cso);
|
||||||
cso_restore_rasterizer(cso);
|
cso_restore_rasterizer(cso);
|
||||||
cso_restore_sample_mask(cso);
|
cso_restore_sample_mask(cso);
|
||||||
|
cso_restore_min_samples(cso);
|
||||||
cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
|
cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
|
cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_restore_stencil_ref(cso);
|
cso_restore_stencil_ref(cso);
|
||||||
|
@@ -520,6 +520,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
|
|||||||
cso_save_depth_stencil_alpha(ctx->cso);
|
cso_save_depth_stencil_alpha(ctx->cso);
|
||||||
cso_save_rasterizer(ctx->cso);
|
cso_save_rasterizer(ctx->cso);
|
||||||
cso_save_sample_mask(ctx->cso);
|
cso_save_sample_mask(ctx->cso);
|
||||||
|
cso_save_min_samples(ctx->cso);
|
||||||
cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
|
cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
|
cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_save_stream_outputs(ctx->cso);
|
cso_save_stream_outputs(ctx->cso);
|
||||||
@@ -535,6 +536,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
|
|||||||
cso_set_blend(ctx->cso, &ctx->blend_write_color);
|
cso_set_blend(ctx->cso, &ctx->blend_write_color);
|
||||||
cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil);
|
cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil);
|
||||||
cso_set_sample_mask(ctx->cso, ~0);
|
cso_set_sample_mask(ctx->cso, ~0);
|
||||||
|
cso_set_min_samples(ctx->cso, 1);
|
||||||
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
|
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
|
||||||
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
|
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
|
||||||
cso_set_stream_outputs(ctx->cso, 0, NULL, NULL);
|
cso_set_stream_outputs(ctx->cso, 0, NULL, NULL);
|
||||||
@@ -597,6 +599,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
|
|||||||
cso_restore_depth_stencil_alpha(ctx->cso);
|
cso_restore_depth_stencil_alpha(ctx->cso);
|
||||||
cso_restore_rasterizer(ctx->cso);
|
cso_restore_rasterizer(ctx->cso);
|
||||||
cso_restore_sample_mask(ctx->cso);
|
cso_restore_sample_mask(ctx->cso);
|
||||||
|
cso_restore_min_samples(ctx->cso);
|
||||||
cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
|
cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
|
cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
|
||||||
cso_restore_viewport(ctx->cso);
|
cso_restore_viewport(ctx->cso);
|
||||||
|
@@ -61,6 +61,7 @@ static const struct st_tracked_state *atoms[] =
|
|||||||
&st_update_sampler, /* depends on update_*_texture for swizzle */
|
&st_update_sampler, /* depends on update_*_texture for swizzle */
|
||||||
&st_update_framebuffer,
|
&st_update_framebuffer,
|
||||||
&st_update_msaa,
|
&st_update_msaa,
|
||||||
|
&st_update_sample_shading,
|
||||||
&st_update_vs_constants,
|
&st_update_vs_constants,
|
||||||
&st_update_gs_constants,
|
&st_update_gs_constants,
|
||||||
&st_update_fs_constants,
|
&st_update_fs_constants,
|
||||||
|
@@ -59,6 +59,7 @@ extern const struct st_tracked_state st_update_viewport;
|
|||||||
extern const struct st_tracked_state st_update_scissor;
|
extern const struct st_tracked_state st_update_scissor;
|
||||||
extern const struct st_tracked_state st_update_blend;
|
extern const struct st_tracked_state st_update_blend;
|
||||||
extern const struct st_tracked_state st_update_msaa;
|
extern const struct st_tracked_state st_update_msaa;
|
||||||
|
extern const struct st_tracked_state st_update_sample_shading;
|
||||||
extern const struct st_tracked_state st_update_sampler;
|
extern const struct st_tracked_state st_update_sampler;
|
||||||
extern const struct st_tracked_state st_update_fragment_texture;
|
extern const struct st_tracked_state st_update_fragment_texture;
|
||||||
extern const struct st_tracked_state st_update_vertex_texture;
|
extern const struct st_tracked_state st_update_vertex_texture;
|
||||||
|
@@ -27,8 +27,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "st_context.h"
|
#include "st_context.h"
|
||||||
|
#include "pipe/p_screen.h"
|
||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
#include "st_atom.h"
|
#include "st_atom.h"
|
||||||
|
#include "st_program.h"
|
||||||
|
|
||||||
#include "cso_cache/cso_context.h"
|
#include "cso_cache/cso_context.h"
|
||||||
#include "util/u_framebuffer.h"
|
#include "util/u_framebuffer.h"
|
||||||
@@ -70,6 +72,18 @@ static void update_sample_mask( struct st_context *st )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_sample_shading( struct st_context *st )
|
||||||
|
{
|
||||||
|
if (!st->fp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!st->ctx->Extensions.ARB_sample_shading)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cso_set_min_samples(
|
||||||
|
st->cso_context,
|
||||||
|
_mesa_get_min_invocations_per_fragment(st->ctx, &st->fp->Base, false));
|
||||||
|
}
|
||||||
|
|
||||||
const struct st_tracked_state st_update_msaa = {
|
const struct st_tracked_state st_update_msaa = {
|
||||||
"st_update_msaa", /* name */
|
"st_update_msaa", /* name */
|
||||||
@@ -79,3 +93,12 @@ const struct st_tracked_state st_update_msaa = {
|
|||||||
},
|
},
|
||||||
update_sample_mask /* update */
|
update_sample_mask /* update */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct st_tracked_state st_update_sample_shading = {
|
||||||
|
"st_update_sample_shading", /* name */
|
||||||
|
{ /* dirty */
|
||||||
|
(_NEW_MULTISAMPLE | _NEW_PROGRAM | _NEW_BUFFERS), /* mesa */
|
||||||
|
ST_NEW_FRAGMENT_PROGRAM | ST_NEW_FRAMEBUFFER, /* st */
|
||||||
|
},
|
||||||
|
update_sample_shading /* update */
|
||||||
|
};
|
||||||
|
@@ -240,6 +240,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
|
|||||||
cso_save_depth_stencil_alpha(st->cso_context);
|
cso_save_depth_stencil_alpha(st->cso_context);
|
||||||
cso_save_rasterizer(st->cso_context);
|
cso_save_rasterizer(st->cso_context);
|
||||||
cso_save_sample_mask(st->cso_context);
|
cso_save_sample_mask(st->cso_context);
|
||||||
|
cso_save_min_samples(st->cso_context);
|
||||||
cso_save_viewport(st->cso_context);
|
cso_save_viewport(st->cso_context);
|
||||||
cso_save_fragment_shader(st->cso_context);
|
cso_save_fragment_shader(st->cso_context);
|
||||||
cso_save_stream_outputs(st->cso_context);
|
cso_save_stream_outputs(st->cso_context);
|
||||||
@@ -309,6 +310,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
|
|||||||
cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
|
cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
|
||||||
cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
|
cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
|
||||||
cso_set_sample_mask(st->cso_context, ~0);
|
cso_set_sample_mask(st->cso_context, ~0);
|
||||||
|
cso_set_min_samples(st->cso_context, 1);
|
||||||
cso_set_rasterizer(st->cso_context, &st->clear.raster);
|
cso_set_rasterizer(st->cso_context, &st->clear.raster);
|
||||||
|
|
||||||
/* viewport state: viewport matching window dims */
|
/* viewport state: viewport matching window dims */
|
||||||
@@ -348,6 +350,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
|
|||||||
cso_restore_depth_stencil_alpha(st->cso_context);
|
cso_restore_depth_stencil_alpha(st->cso_context);
|
||||||
cso_restore_rasterizer(st->cso_context);
|
cso_restore_rasterizer(st->cso_context);
|
||||||
cso_restore_sample_mask(st->cso_context);
|
cso_restore_sample_mask(st->cso_context);
|
||||||
|
cso_restore_min_samples(st->cso_context);
|
||||||
cso_restore_viewport(st->cso_context);
|
cso_restore_viewport(st->cso_context);
|
||||||
cso_restore_fragment_shader(st->cso_context);
|
cso_restore_fragment_shader(st->cso_context);
|
||||||
cso_restore_vertex_shader(st->cso_context);
|
cso_restore_vertex_shader(st->cso_context);
|
||||||
|
@@ -425,7 +425,8 @@ void st_init_extensions(struct st_context *st)
|
|||||||
{ o(OES_standard_derivatives), PIPE_CAP_SM3 },
|
{ o(OES_standard_derivatives), PIPE_CAP_SM3 },
|
||||||
{ o(ARB_texture_cube_map_array), PIPE_CAP_CUBE_MAP_ARRAY },
|
{ o(ARB_texture_cube_map_array), PIPE_CAP_CUBE_MAP_ARRAY },
|
||||||
{ o(ARB_texture_multisample), PIPE_CAP_TEXTURE_MULTISAMPLE },
|
{ o(ARB_texture_multisample), PIPE_CAP_TEXTURE_MULTISAMPLE },
|
||||||
{ o(ARB_texture_query_lod), PIPE_CAP_TEXTURE_QUERY_LOD }
|
{ o(ARB_texture_query_lod), PIPE_CAP_TEXTURE_QUERY_LOD },
|
||||||
|
{ o(ARB_sample_shading), PIPE_CAP_SAMPLE_SHADING },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Required: render target and sampler support */
|
/* Required: render target and sampler support */
|
||||||
|
@@ -4163,7 +4163,9 @@ struct st_translate {
|
|||||||
static unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = {
|
static unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = {
|
||||||
TGSI_SEMANTIC_FACE,
|
TGSI_SEMANTIC_FACE,
|
||||||
TGSI_SEMANTIC_VERTEXID,
|
TGSI_SEMANTIC_VERTEXID,
|
||||||
TGSI_SEMANTIC_INSTANCEID
|
TGSI_SEMANTIC_INSTANCEID,
|
||||||
|
TGSI_SEMANTIC_SAMPLEID,
|
||||||
|
TGSI_SEMANTIC_SAMPLEPOS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4381,7 +4383,8 @@ translate_dst(struct st_translate *t,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TGSI_PROCESSOR_FRAGMENT:
|
case TGSI_PROCESSOR_FRAGMENT:
|
||||||
if (dst_reg->index >= FRAG_RESULT_COLOR) {
|
if (dst_reg->index == FRAG_RESULT_COLOR ||
|
||||||
|
dst_reg->index >= FRAG_RESULT_DATA0) {
|
||||||
dst = ureg_saturate(dst);
|
dst = ureg_saturate(dst);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4876,6 +4879,15 @@ st_translate_program(
|
|||||||
TGSI_SEMANTIC_COLOR,
|
TGSI_SEMANTIC_COLOR,
|
||||||
outputSemanticIndex[i]);
|
outputSemanticIndex[i]);
|
||||||
break;
|
break;
|
||||||
|
case TGSI_SEMANTIC_SAMPLEMASK:
|
||||||
|
t->outputs[i] = ureg_DECL_output(ureg,
|
||||||
|
TGSI_SEMANTIC_SAMPLEMASK,
|
||||||
|
outputSemanticIndex[i]);
|
||||||
|
/* TODO: If we ever support more than 32 samples, this will have
|
||||||
|
* to become an array.
|
||||||
|
*/
|
||||||
|
t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(!"fragment shader outputs must be POSITION/STENCIL/COLOR");
|
assert(!"fragment shader outputs must be POSITION/STENCIL/COLOR");
|
||||||
ret = PIPE_ERROR_BAD_INPUT;
|
ret = PIPE_ERROR_BAD_INPUT;
|
||||||
|
@@ -682,6 +682,7 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
/* handle remaining outputs (color) */
|
/* handle remaining outputs (color) */
|
||||||
for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
|
for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
|
||||||
if (outputsWritten & BITFIELD64_BIT(attr)) {
|
if (outputsWritten & BITFIELD64_BIT(attr)) {
|
||||||
|
int semantic = TGSI_SEMANTIC_COLOR;
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
case FRAG_RESULT_DEPTH:
|
case FRAG_RESULT_DEPTH:
|
||||||
case FRAG_RESULT_STENCIL:
|
case FRAG_RESULT_STENCIL:
|
||||||
@@ -689,16 +690,20 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
case FRAG_RESULT_COLOR:
|
case FRAG_RESULT_COLOR:
|
||||||
write_all = GL_TRUE; /* fallthrough */
|
write_all = GL_TRUE;
|
||||||
default:
|
break;
|
||||||
|
case FRAG_RESULT_SAMPLE_MASK:
|
||||||
|
semantic = TGSI_SEMANTIC_SAMPLEMASK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
assert(attr == FRAG_RESULT_COLOR ||
|
assert(attr == FRAG_RESULT_COLOR ||
|
||||||
|
attr == FRAG_RESULT_SAMPLE_MASK ||
|
||||||
(FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
|
(FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
|
||||||
fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
|
fs_output_semantic_name[fs_num_outputs] = semantic;
|
||||||
fs_output_semantic_index[fs_num_outputs] = numColors;
|
fs_output_semantic_index[fs_num_outputs] = numColors;
|
||||||
outputMapping[attr] = fs_num_outputs;
|
outputMapping[attr] = fs_num_outputs;
|
||||||
numColors++;
|
numColors++;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs_num_outputs++;
|
fs_num_outputs++;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user