X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_tgsi.c;h=4c16f4313a0bc2c7b9529254c997db112af6af6f;hb=b00e3f221b3f6dd0e87697c53331fd033b6e8676;hp=0cd620189b7b5c691fde43ba5ab5ed76b3fcca08;hpb=5ac16495a2772886100789f04e1a7d65068e9a40;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_tgsi.c b/src/gallium/drivers/svga/svga_tgsi.c index 0cd620189b7..4c16f4313a0 100644 --- a/src/gallium/drivers/svga/svga_tgsi.c +++ b/src/gallium/drivers/svga/svga_tgsi.c @@ -30,12 +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" @@ -49,7 +51,8 @@ static char err_buf[128]; #if 0 -static void svga_destroy_shader_emitter( struct svga_shader_emitter *emit ) +static void +svga_destroy_shader_emitter(struct svga_shader_emitter *emit) { if (emit->buf != err_buf) FREE(emit->buf); @@ -57,12 +60,13 @@ static void svga_destroy_shader_emitter( struct svga_shader_emitter *emit ) #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; @@ -78,205 +82,189 @@ 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; 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; + + if (emit.nr_hw_temp >= SVGA3D_TEMPREG_MAX) { + debug_printf("svga: too many temporary registers (%u)\n", + emit.nr_hw_temp); + goto fail; + } + emit.in_main_func = TRUE; - if (!svga_shader_emit_header( &emit )) + if (!svga_shader_emit_header(&emit)) { + debug_printf("svga: emit header failed\n"); goto fail; + } - if (!svga_shader_emit_instructions( &emit, shader->tokens )) + if (!svga_shader_emit_instructions(&emit, shader->tokens)) { + debug_printf("svga: emit instructions failed\n"); goto fail; - - result = CALLOC_STRUCT(svga_shader_result); - if (result == NULL) + } + + variant = svga_new_shader_variant(svga); + if (variant == 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); - result->id = UTIL_BITMASK_INVALID_INDEX; - - if (SVGA_DEBUG & DEBUG_TGSI) - { - debug_printf( "#####################################\n" ); - debug_printf( "Shader %u below\n", shader->id ); - tgsi_dump( shader->tokens, 0 ); + 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; + + variant->pstipple_sampler_unit = emit.pstipple_sampler_unit; + + /* 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; + +#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( result->tokens, - result->nr_tokens , - FALSE ); + debug_printf("Shader %u compiled below\n", shader->id); + svga_shader_dump(variant->tokens, variant->nr_tokens, FALSE); } - debug_printf( "#####################################\n" ); + debug_printf("#####################################\n"); } +#endif - return result; + return variant; -fail: - FREE(result); + fail: + FREE(variant); FREE(emit.buf); return NULL; } - - - - -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); - - return svga_tgsi_translate( &fs->base, - key, - PIPE_SHADER_FRAGMENT ); -} - -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); - - return svga_tgsi_translate( &vs->base, - key, - PIPE_SHADER_VERTEX ); -} - - -void svga_destroy_shader_result( struct svga_shader_result *result ) -{ - FREE((unsigned *)result->tokens); - FREE(result); -} -