summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/svga/svga_tgsi_decl_sm20.c')
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_decl_sm20.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
new file mode 100644
index 00000000000..54457082a06
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
@@ -0,0 +1,280 @@
+/**********************************************************
+ * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ *
+ * 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 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 "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "util/u_memory.h"
+
+#include "svga_tgsi_emit.h"
+#include "svga_context.h"
+
+
+
+
+static boolean ps20_input( struct svga_shader_emitter *emit,
+ struct tgsi_declaration_semantic semantic,
+ unsigned idx )
+{
+ struct src_register reg;
+ SVGA3DOpDclArgs dcl;
+ SVGA3dShaderInstToken opcode;
+
+ opcode = inst_token( SVGA3DOP_DCL );
+ dcl.values[0] = 0;
+ dcl.values[1] = 0;
+
+ switch (semantic.SemanticName) {
+ case TGSI_SEMANTIC_POSITION:
+ /* Special case:
+ */
+ reg = src_register( SVGA3DREG_MISCTYPE,
+ SVGA3DMISCREG_POSITION );
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ reg = src_register( SVGA3DREG_INPUT,
+ semantic.SemanticIndex );
+ break;
+ case TGSI_SEMANTIC_FOG:
+ assert(semantic.SemanticIndex == 0);
+ reg = src_register( SVGA3DREG_TEXTURE, 0 );
+ break;
+ case TGSI_SEMANTIC_GENERIC:
+ reg = src_register( SVGA3DREG_TEXTURE,
+ semantic.SemanticIndex + 1 );
+ break;
+ default:
+ assert(0);
+ return TRUE;
+ }
+
+ emit->input_map[idx] = reg;
+
+ dcl.dst = dst( reg );
+
+ dcl.usage = 0;
+ dcl.index = 0;
+
+ dcl.values[0] |= 1<<31;
+
+ return (emit_instruction(emit, opcode) &&
+ svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+
+static boolean ps20_output( struct svga_shader_emitter *emit,
+ struct tgsi_declaration_semantic semantic,
+ unsigned idx )
+{
+ SVGA3dShaderDestToken reg;
+
+ switch (semantic.SemanticName) {
+ case TGSI_SEMANTIC_COLOR:
+ if (semantic.SemanticIndex < PIPE_MAX_COLOR_BUFS) {
+ unsigned cbuf = semantic.SemanticIndex;
+
+ emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+ emit->nr_hw_temp++ );
+ emit->temp_col[cbuf] = emit->output_map[idx];
+ emit->true_col[cbuf] = dst_register( SVGA3DREG_COLOROUT,
+ semantic.SemanticIndex );
+ }
+ else {
+ assert(0);
+ reg = dst_register( SVGA3DREG_COLOROUT, 0 );
+ }
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+ emit->nr_hw_temp++ );
+ emit->temp_pos = emit->output_map[idx];
+ emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT,
+ semantic.SemanticIndex );
+ break;
+ default:
+ assert(0);
+ reg = dst_register( SVGA3DREG_COLOROUT, 0 );
+ break;
+ }
+
+ return TRUE;
+}
+
+
+static boolean vs20_input( struct svga_shader_emitter *emit,
+ struct tgsi_declaration_semantic semantic,
+ unsigned idx )
+{
+ SVGA3DOpDclArgs dcl;
+ SVGA3dShaderInstToken opcode;
+
+ opcode = inst_token( SVGA3DOP_DCL );
+ dcl.values[0] = 0;
+ dcl.values[1] = 0;
+
+ emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
+ dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
+
+ assert(dcl.dst.reserved0);
+
+ /* Mesa doesn't provide use with VS input semantics (they're
+ * actually pretty meaningless), so we just generate some plausible
+ * ones here. This has to match what we declare in the vdecl code
+ * in svga_pipe_vertex.c.
+ */
+ if (idx == 0) {
+ dcl.usage = SVGA3D_DECLUSAGE_POSITION;
+ dcl.index = 0;
+ }
+ else {
+ dcl.usage = SVGA3D_DECLUSAGE_TEXCOORD;
+ dcl.index = idx - 1;
+ }
+
+ dcl.values[0] |= 1<<31;
+
+ return (emit_instruction(emit, opcode) &&
+ svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+
+static boolean vs20_output( struct svga_shader_emitter *emit,
+ struct tgsi_declaration_semantic semantic,
+ unsigned idx )
+{
+ /* Don't emit dcl instruction for vs20 inputs
+ */
+
+ /* Just build the register map table:
+ */
+ switch (semantic.SemanticName) {
+ case TGSI_SEMANTIC_POSITION:
+ assert(semantic.SemanticIndex == 0);
+ emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+ emit->nr_hw_temp++ );
+ emit->temp_pos = emit->output_map[idx];
+ emit->true_pos = dst_register( SVGA3DREG_RASTOUT,
+ SVGA3DRASTOUT_POSITION);
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ assert(semantic.SemanticIndex == 0);
+ emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+ emit->nr_hw_temp++ );
+ emit->temp_psiz = emit->output_map[idx];
+ emit->true_psiz = dst_register( SVGA3DREG_RASTOUT,
+ SVGA3DRASTOUT_PSIZE );
+ break;
+ case TGSI_SEMANTIC_FOG:
+ assert(semantic.SemanticIndex == 0);
+ emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT, 0 );
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ /* oD0 */
+ emit->output_map[idx] = dst_register( SVGA3DREG_ATTROUT,
+ semantic.SemanticIndex );
+ break;
+ case TGSI_SEMANTIC_GENERIC:
+ emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT,
+ semantic.SemanticIndex + 1 );
+ break;
+ default:
+ assert(0);
+ emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, 0 );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static boolean ps20_sampler( struct svga_shader_emitter *emit,
+ struct tgsi_declaration_semantic semantic,
+ unsigned idx )
+{
+ SVGA3DOpDclArgs dcl;
+ SVGA3dShaderInstToken opcode;
+
+ opcode = inst_token( SVGA3DOP_DCL );
+ dcl.values[0] = 0;
+ dcl.values[1] = 0;
+
+ dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
+ dcl.type = svga_tgsi_sampler_type( emit, idx );
+
+ return (emit_instruction(emit, opcode) &&
+ svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+
+boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
+ const struct tgsi_full_declaration *decl )
+{
+ unsigned first = decl->DeclarationRange.First;
+ unsigned last = decl->DeclarationRange.Last;
+ unsigned semantic = 0;
+ unsigned semantic_idx = 0;
+ unsigned idx;
+
+ if (decl->Declaration.Semantic) {
+ semantic = decl->Semantic.SemanticName;
+ semantic_idx = decl->Semantic.SemanticIndex;
+ }
+
+ for( idx = first; idx <= last; idx++ ) {
+ boolean ok;
+
+ switch (decl->Declaration.File) {
+ case TGSI_FILE_SAMPLER:
+ assert (emit->unit == PIPE_SHADER_FRAGMENT);
+ ok = ps20_sampler( emit, decl->Semantic, idx );
+ break;
+
+ case TGSI_FILE_INPUT:
+ if (emit->unit == PIPE_SHADER_VERTEX)
+ ok = vs20_input( emit, decl->Semantic, idx );
+ else
+ ok = ps20_input( emit, decl->Semantic, idx );
+ break;
+
+ case TGSI_FILE_OUTPUT:
+ if (emit->unit == PIPE_SHADER_VERTEX)
+ ok = vs20_output( emit, decl->Semantic, idx );
+ else
+ ok = ps20_output( emit, decl->Semantic, idx );
+ break;
+
+ default:
+ /* don't need to declare other vars */
+ ok = TRUE;
+ }
+
+ if (!ok)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+