X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_tgsi.c;h=7cbd5166900e70fbe5911b1f42b70688ae72a1e3;hb=b1772651b728fd231b0c5885415b35f43a307c7f;hp=81eea1a145aff7c99e89f4ded22cbd4c7c08718b;hpb=178407f33c413cbe7434597b2129abde90041b6b;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_tgsi.c b/src/gallium/drivers/svga/svga_tgsi.c index 81eea1a145a..7cbd5166900 100644 --- a/src/gallium/drivers/svga/svga_tgsi.c +++ b/src/gallium/drivers/svga/svga_tgsi.c @@ -30,11 +30,14 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_scan.h" +#include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_bitmask.h" #include "svgadump/svga_shader_dump.h" #include "svga_context.h" +#include "svga_shader.h" #include "svga_tgsi.h" #include "svga_tgsi_emit.h" #include "svga_debug.h" @@ -47,26 +50,19 @@ */ static char err_buf[128]; -#if 0 -static void svga_destroy_shader_emitter( struct svga_shader_emitter *emit ) -{ - if (emit->buf != err_buf) - FREE(emit->buf); -} -#endif - -static boolean svga_shader_expand( struct svga_shader_emitter *emit ) +static boolean +svga_shader_expand(struct svga_shader_emitter *emit) { char *new_buf; unsigned newsize = emit->size * 2; - if(emit->buf != err_buf) + if (emit->buf != err_buf) new_buf = REALLOC(emit->buf, emit->size, newsize); else new_buf = NULL; - if (new_buf == NULL) { + if (!new_buf) { emit->ptr = err_buf; emit->buf = err_buf; emit->size = sizeof(err_buf); @@ -77,190 +73,196 @@ static boolean svga_shader_expand( struct svga_shader_emitter *emit ) emit->ptr = new_buf + (emit->ptr - emit->buf); emit->buf = new_buf; return TRUE; -} +} + -static INLINE boolean reserve( struct svga_shader_emitter *emit, - unsigned nr_dwords ) +static inline boolean +reserve(struct svga_shader_emitter *emit, unsigned nr_dwords) { if (emit->ptr - emit->buf + nr_dwords * sizeof(unsigned) >= emit->size) { - if (!svga_shader_expand( emit )) + if (!svga_shader_expand(emit)) { return FALSE; + } } return TRUE; } -boolean svga_shader_emit_dword( struct svga_shader_emitter *emit, - unsigned dword ) + +boolean +svga_shader_emit_dword(struct svga_shader_emitter * emit, unsigned dword) { if (!reserve(emit, 1)) return FALSE; - *(unsigned *)emit->ptr = dword; + *(unsigned *) emit->ptr = dword; emit->ptr += sizeof dword; return TRUE; } -boolean svga_shader_emit_dwords( struct svga_shader_emitter *emit, - const unsigned *dwords, - unsigned nr ) + +boolean +svga_shader_emit_dwords(struct svga_shader_emitter * emit, + const unsigned *dwords, unsigned nr) { if (!reserve(emit, nr)) return FALSE; - memcpy( emit->ptr, dwords, nr * sizeof *dwords ); + memcpy(emit->ptr, dwords, nr * sizeof *dwords); emit->ptr += nr * sizeof *dwords; return TRUE; } -boolean svga_shader_emit_opcode( struct svga_shader_emitter *emit, - unsigned opcode ) + +boolean +svga_shader_emit_opcode(struct svga_shader_emitter * emit, unsigned opcode) { SVGA3dShaderInstToken *here; if (!reserve(emit, 1)) return FALSE; - here = (SVGA3dShaderInstToken *)emit->ptr; + here = (SVGA3dShaderInstToken *) emit->ptr; here->value = opcode; if (emit->insn_offset) { - SVGA3dShaderInstToken *prev = (SVGA3dShaderInstToken *)(emit->buf + - emit->insn_offset); + SVGA3dShaderInstToken *prev = + (SVGA3dShaderInstToken *) (emit->buf + emit->insn_offset); prev->size = (here - prev) - 1; } - + emit->insn_offset = emit->ptr - emit->buf; emit->ptr += sizeof(unsigned); return TRUE; } -#define SVGA3D_PS_2X (SVGA3D_PS_20 | 1) -#define SVGA3D_VS_2X (SVGA3D_VS_20 | 1) -static boolean svga_shader_emit_header( struct svga_shader_emitter *emit ) +static boolean +svga_shader_emit_header(struct svga_shader_emitter *emit) { SVGA3dShaderVersion header; - memset( &header, 0, sizeof header ); + memset(&header, 0, sizeof header); switch (emit->unit) { case PIPE_SHADER_FRAGMENT: - header.value = emit->use_sm30 ? SVGA3D_PS_30 : SVGA3D_PS_2X; + header.value = SVGA3D_PS_30; break; case PIPE_SHADER_VERTEX: - header.value = emit->use_sm30 ? SVGA3D_VS_30 : SVGA3D_VS_2X; + header.value = SVGA3D_VS_30; break; } - - return svga_shader_emit_dword( emit, header.value ); -} - - + return svga_shader_emit_dword(emit, header.value); +} -/* Parse TGSI shader and translate to SVGA/DX9 serialized - * representation. +/** + * Parse TGSI shader and translate to SVGA/DX9 serialized + * representation. * * In this function SVGA shader is emitted to an in-memory buffer that * can be dynamically grown. Once we've finished and know how large * it is, it will be copied to a hardware buffer for upload. */ -static struct svga_shader_result * -svga_tgsi_translate( const struct svga_shader *shader, - union svga_compile_key key, - unsigned unit ) +struct svga_shader_variant * +svga_tgsi_vgpu9_translate(struct svga_context *svga, + const struct svga_shader *shader, + const struct svga_compile_key *key, unsigned unit) { - struct svga_shader_result *result = NULL; + struct svga_shader_variant *variant = NULL; struct svga_shader_emitter emit; - int ret = 0; + + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_TGSIVGPU9TRANSLATE); memset(&emit, 0, sizeof(emit)); - emit.use_sm30 = shader->use_sm30; emit.size = 1024; emit.buf = MALLOC(emit.size); if (emit.buf == NULL) { - ret = PIPE_ERROR_OUT_OF_MEMORY; goto fail; } emit.ptr = emit.buf; emit.unit = unit; - emit.key = key; + emit.key = *key; - tgsi_scan_shader( shader->tokens, &emit.info); + tgsi_scan_shader(shader->tokens, &emit.info); emit.imm_start = emit.info.file_max[TGSI_FILE_CONSTANT] + 1; - + if (unit == PIPE_SHADER_FRAGMENT) - emit.imm_start += key.fkey.num_unnormalized_coords; + emit.imm_start += key->num_unnormalized_coords; if (unit == PIPE_SHADER_VERTEX) { - emit.imm_start += key.vkey.need_prescale ? 2 : 0; - emit.imm_start += key.vkey.num_zero_stride_vertex_elements; + emit.imm_start += key->vs.need_prescale ? 2 : 0; } - emit.nr_hw_const = (emit.imm_start + emit.info.file_max[TGSI_FILE_IMMEDIATE] + 1); + emit.nr_hw_float_const = + (emit.imm_start + emit.info.file_max[TGSI_FILE_IMMEDIATE] + 1); emit.nr_hw_temp = emit.info.file_max[TGSI_FILE_TEMPORARY] + 1; - emit.in_main_func = TRUE; - - if (!svga_shader_emit_header( &emit )) - goto fail; - if (!svga_shader_emit_instructions( &emit, shader->tokens )) + if (emit.nr_hw_temp >= SVGA3D_TEMPREG_MAX) { + debug_printf("svga: too many temporary registers (%u)\n", + emit.nr_hw_temp); goto fail; - - result = CALLOC_STRUCT(svga_shader_result); - if (result == NULL) - goto fail; - - result->shader = shader; - result->tokens = (const unsigned *)emit.buf; - result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned); - memcpy(&result->key, &key, sizeof key); - - return result; + } -fail: - FREE(result); - FREE(emit.buf); - return NULL; -} + emit.in_main_func = TRUE; + if (!svga_shader_emit_header(&emit)) { + debug_printf("svga: emit header failed\n"); + goto fail; + } + if (!svga_shader_emit_instructions(&emit, shader->tokens)) { + debug_printf("svga: emit instructions failed\n"); + goto fail; + } + variant = svga_new_shader_variant(svga); + if (!variant) + goto fail; -struct svga_shader_result * -svga_translate_fragment_program( const struct svga_fragment_shader *fs, - const struct svga_fs_compile_key *fkey ) -{ - union svga_compile_key key; - memcpy(&key.fkey, fkey, sizeof *fkey); + variant->shader = shader; + variant->tokens = (const unsigned *) emit.buf; + variant->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned); + memcpy(&variant->key, key, sizeof(*key)); + variant->id = UTIL_BITMASK_INVALID_INDEX; - return svga_tgsi_translate( &fs->base, - key, - PIPE_SHADER_FRAGMENT ); -} + variant->pstipple_sampler_unit = emit.pstipple_sampler_unit; -struct svga_shader_result * -svga_translate_vertex_program( const struct svga_vertex_shader *vs, - const struct svga_vs_compile_key *vkey ) -{ - union svga_compile_key key; - memcpy(&key.vkey, vkey, sizeof *vkey); + /* If there was exactly one write to a fragment shader output register + * and it came from a constant buffer, we know all fragments will have + * the same color (except for blending). + */ + variant->constant_color_output = + emit.constant_color_output && emit.num_output_writes == 1; - return svga_tgsi_translate( &vs->base, - key, - PIPE_SHADER_VERTEX ); -} +#if 0 + if (!svga_shader_verify(variant->tokens, variant->nr_tokens) || + SVGA_DEBUG & DEBUG_TGSI) { + debug_printf("#####################################\n"); + debug_printf("Shader %u below\n", shader->id); + tgsi_dump(shader->tokens, 0); + if (SVGA_DEBUG & DEBUG_TGSI) { + debug_printf("Shader %u compiled below\n", shader->id); + svga_shader_dump(variant->tokens, variant->nr_tokens, FALSE); + } + debug_printf("#####################################\n"); + } +#endif + goto done; -void svga_destroy_shader_result( struct svga_shader_result *result ) -{ - FREE((unsigned *)result->tokens); - FREE(result); +fail: + FREE(variant); + if (emit.buf != err_buf) + FREE(emit.buf); + variant = NULL; + +done: + SVGA_STATS_TIME_POP(svga_sws(svga)); + return variant; } -