r300g: clean up derived states
The state setups which aren't derived anymore have been moved to the VS and FS objects.
This commit is contained in:
parent
6f05eba020
commit
cb90235135
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
|
||||
* Joakim Sindholt <opensource@zhasha.com>
|
||||
* Copyright 2009 Marek Olšák <maraeo@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -31,6 +32,40 @@
|
|||
#include "radeon_code.h"
|
||||
#include "radeon_compiler.h"
|
||||
|
||||
/* Convert info about FS input semantics to r300_shader_semantics. */
|
||||
static void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
|
||||
struct r300_shader_semantics* fs_inputs)
|
||||
{
|
||||
int i;
|
||||
unsigned index;
|
||||
|
||||
r300_shader_semantics_reset(fs_inputs);
|
||||
|
||||
for (i = 0; i < info->num_inputs; i++) {
|
||||
index = info->input_semantic_index[i];
|
||||
|
||||
switch (info->input_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
assert(index <= ATTR_COLOR_COUNT);
|
||||
fs_inputs->color[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
assert(index <= ATTR_GENERIC_COUNT);
|
||||
fs_inputs->generic[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
assert(index == 0);
|
||||
fs_inputs->fog = i;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void find_output_registers(struct r300_fragment_program_compiler * compiler,
|
||||
struct r300_fragment_shader * fs)
|
||||
{
|
||||
|
@ -98,6 +133,10 @@ void r300_translate_fragment_shader(struct r300_context* r300,
|
|||
struct r300_fragment_program_compiler compiler;
|
||||
struct tgsi_to_rc ttr;
|
||||
|
||||
/* Initialize. */
|
||||
r300_shader_read_fs_inputs(&fs->info, &fs->inputs);
|
||||
|
||||
/* Setup the compiler. */
|
||||
memset(&compiler, 0, sizeof(compiler));
|
||||
rc_init(&compiler.Base);
|
||||
compiler.Base.Debug = DBG_ON(r300, DBG_FP);
|
||||
|
@ -107,7 +146,7 @@ void r300_translate_fragment_shader(struct r300_context* r300,
|
|||
compiler.AllocateHwInputs = &allocate_hardware_inputs;
|
||||
compiler.UserData = fs;
|
||||
|
||||
/* TODO: Program compilation depends on texture compare modes,
|
||||
/* XXX: Program compilation depends on texture compare modes,
|
||||
* which are sampler state. Therefore, programs need to be recompiled
|
||||
* depending on this state as in the classic Mesa driver.
|
||||
*
|
||||
|
@ -133,6 +172,7 @@ void r300_translate_fragment_shader(struct r300_context* r300,
|
|||
/* XXX failover maybe? */
|
||||
DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n",
|
||||
compiler.Base.ErrorMsg);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* And, finally... */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
|
||||
* Joakim Sindholt <opensource@zhasha.com>
|
||||
* Copyright 2009 Marek Olšák <maraeo@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,15 +26,16 @@
|
|||
#define R300_FS_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
|
||||
#include "radeon_code.h"
|
||||
#include "r300_shader_semantics.h"
|
||||
|
||||
struct r300_fragment_shader {
|
||||
/* Parent class */
|
||||
struct pipe_shader_state state;
|
||||
|
||||
struct tgsi_shader_info info;
|
||||
struct r300_shader_semantics inputs;
|
||||
|
||||
/* Has this shader been translated yet? */
|
||||
boolean translated;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2009 Marek Olšák <maraeo@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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. */
|
||||
|
||||
#ifndef R300_SHADER_SEMANTICS_H
|
||||
#define R300_SHADER_SEMANTICS_H
|
||||
|
||||
#define ATTR_UNUSED (-1)
|
||||
#define ATTR_COLOR_COUNT 2
|
||||
#define ATTR_GENERIC_COUNT 16
|
||||
|
||||
/* This structure contains information about what attributes are written by VS
|
||||
* or read by FS. (but not both) It's much easier to work with than
|
||||
* tgsi_shader_info.
|
||||
*
|
||||
* The variables contain indices to tgsi_shader_info semantics and those
|
||||
* indices are nothing else than input/output register numbers. */
|
||||
struct r300_shader_semantics {
|
||||
int pos;
|
||||
int psize;
|
||||
int color[ATTR_COLOR_COUNT];
|
||||
int bcolor[ATTR_COLOR_COUNT];
|
||||
int generic[ATTR_GENERIC_COUNT];
|
||||
int fog;
|
||||
};
|
||||
|
||||
static INLINE void r300_shader_semantics_reset(
|
||||
struct r300_shader_semantics* info)
|
||||
{
|
||||
int i;
|
||||
|
||||
info->pos = ATTR_UNUSED;
|
||||
info->psize = ATTR_UNUSED;
|
||||
info->fog = ATTR_UNUSED;
|
||||
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
info->color[i] = ATTR_UNUSED;
|
||||
info->bcolor[i] = ATTR_UNUSED;
|
||||
}
|
||||
|
||||
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
|
||||
info->generic[i] = ATTR_UNUSED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -29,6 +29,7 @@
|
|||
#include "r300_context.h"
|
||||
#include "r300_fs.h"
|
||||
#include "r300_screen.h"
|
||||
#include "r300_shader_semantics.h"
|
||||
#include "r300_state_derived.h"
|
||||
#include "r300_state_inlines.h"
|
||||
#include "r300_vs.h"
|
||||
|
@ -36,25 +37,6 @@
|
|||
/* r300_state_derived: Various bits of state which are dependent upon
|
||||
* currently bound CSO data. */
|
||||
|
||||
#define ATTR_UNUSED (-1)
|
||||
#define ATTR_COLOR_COUNT 2
|
||||
#define ATTR_GENERIC_COUNT 16
|
||||
|
||||
/* This structure contains information about what attributes are written by VS
|
||||
* or read by FS. (but not both) It's much easier to work with than
|
||||
* tgsi_shader_info.
|
||||
*
|
||||
* The variables basically means used/unused and may optionally contain
|
||||
* indices to tgsi_shader_info semantics which we need to know for Draw. */
|
||||
struct r300_shader_info {
|
||||
int pos;
|
||||
int psize;
|
||||
int color[ATTR_COLOR_COUNT];
|
||||
int bcolor[ATTR_COLOR_COUNT];
|
||||
int generic[ATTR_GENERIC_COUNT];
|
||||
int fog;
|
||||
};
|
||||
|
||||
struct r300_shader_key {
|
||||
struct r300_vertex_shader* vs;
|
||||
struct r300_fragment_shader* fs;
|
||||
|
@ -89,193 +71,21 @@ static void r300_draw_emit_attrib(struct r300_context* r300,
|
|||
struct tgsi_shader_info* info = &r300->vs->info;
|
||||
int output;
|
||||
|
||||
if (r300->draw) {
|
||||
output = draw_find_vs_output(r300->draw,
|
||||
info->output_semantic_name[index],
|
||||
info->output_semantic_index[index]);
|
||||
draw_emit_vertex_attr(&r300->vertex_info->vinfo, emit, interp, output);
|
||||
}
|
||||
output = draw_find_vs_output(r300->draw,
|
||||
info->output_semantic_name[index],
|
||||
info->output_semantic_index[index]);
|
||||
draw_emit_vertex_attr(&r300->vertex_info->vinfo, emit, interp, output);
|
||||
}
|
||||
|
||||
static void r300_shader_info_reset(struct r300_shader_info* info)
|
||||
static void r300_draw_emit_all_attribs(struct r300_context* r300)
|
||||
{
|
||||
int i;
|
||||
|
||||
info->pos = ATTR_UNUSED;
|
||||
info->psize = ATTR_UNUSED;
|
||||
info->fog = ATTR_UNUSED;
|
||||
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
info->color[i] = ATTR_UNUSED;
|
||||
info->bcolor[i] = ATTR_UNUSED;
|
||||
}
|
||||
|
||||
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
|
||||
info->generic[i] = ATTR_UNUSED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert info about VS output semantics to r300_shader_info. */
|
||||
static void r300_shader_read_vs_outputs(struct tgsi_shader_info* info,
|
||||
struct r300_shader_info* vs_outputs)
|
||||
{
|
||||
int i;
|
||||
unsigned index;
|
||||
|
||||
r300_shader_info_reset(vs_outputs);
|
||||
|
||||
for (i = 0; i < info->num_outputs; i++) {
|
||||
index = info->output_semantic_index[i];
|
||||
|
||||
switch (info->output_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
assert(index == 0);
|
||||
vs_outputs->pos = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_PSIZE:
|
||||
assert(index == 0);
|
||||
vs_outputs->psize = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
assert(index <= ATTR_COLOR_COUNT);
|
||||
vs_outputs->color[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_BCOLOR:
|
||||
assert(index <= ATTR_COLOR_COUNT);
|
||||
vs_outputs->bcolor[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
assert(index <= ATTR_GENERIC_COUNT);
|
||||
vs_outputs->generic[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
assert(index == 0);
|
||||
vs_outputs->fog = i;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set VS output stream locations for SWTCL. */
|
||||
static void r300_stream_locations_swtcl(struct r300_shader_info* vs_outputs,
|
||||
int* vs_output_tab)
|
||||
{
|
||||
int i, tabi = 0, gen_count;
|
||||
|
||||
/* XXX Check whether the numbers (0, 1, 2+i, etc.) are correct.
|
||||
* These should go to VAP_PROG_STREAM_CNTL/DST_VEC_LOC. */
|
||||
|
||||
/* Position. */
|
||||
vs_output_tab[tabi++] = 0;
|
||||
|
||||
/* Point size. */
|
||||
if (vs_outputs->psize != ATTR_UNUSED) {
|
||||
vs_output_tab[tabi++] = 1;
|
||||
}
|
||||
|
||||
/* Colors. */
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
if (vs_outputs->color[i] != ATTR_UNUSED) {
|
||||
vs_output_tab[tabi++] = 2 + i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Back-face colors. */
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
|
||||
vs_output_tab[tabi++] = 4 + i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Texture coordinates. */
|
||||
gen_count = 0;
|
||||
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
|
||||
if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
|
||||
assert(tabi < 16);
|
||||
vs_output_tab[tabi++] = 6 + gen_count;
|
||||
gen_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fog coordinates. */
|
||||
if (vs_outputs->fog != ATTR_UNUSED) {
|
||||
assert(tabi < 16);
|
||||
vs_output_tab[tabi++] = 6 + gen_count;
|
||||
gen_count++;
|
||||
}
|
||||
|
||||
/* XXX magic */
|
||||
assert(gen_count <= 8);
|
||||
|
||||
for (; tabi < 16;) {
|
||||
vs_output_tab[tabi++] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert info about FS input semantics to r300_shader_info. */
|
||||
static void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
|
||||
struct r300_shader_info* fs_inputs)
|
||||
{
|
||||
int i;
|
||||
unsigned index;
|
||||
|
||||
r300_shader_info_reset(fs_inputs);
|
||||
|
||||
for (i = 0; i < info->num_inputs; i++) {
|
||||
index = info->input_semantic_index[i];
|
||||
|
||||
switch (info->input_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
assert(index <= ATTR_COLOR_COUNT);
|
||||
fs_inputs->color[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
assert(index <= ATTR_GENERIC_COUNT);
|
||||
fs_inputs->generic[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
assert(index == 0);
|
||||
fs_inputs->fog = i;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void r300_update_vap_output_fmt(struct r300_context* r300,
|
||||
struct r300_shader_info* vs_outputs)
|
||||
{
|
||||
struct vertex_info* vinfo = &r300->vertex_info->vinfo;
|
||||
struct r300_shader_semantics* vs_outputs = &r300->vs->outputs;
|
||||
int i, gen_count;
|
||||
|
||||
/* Do the actual vertex_info setup.
|
||||
*
|
||||
* vertex_info has four uints of hardware-specific data in it.
|
||||
* vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
|
||||
* vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
|
||||
* vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
|
||||
* vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
|
||||
|
||||
vinfo->hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
|
||||
|
||||
/* Position. */
|
||||
if (vs_outputs->pos != ATTR_UNUSED) {
|
||||
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
|
||||
vs_outputs->pos);
|
||||
vinfo->hwfmt[1] |= R300_INPUT_CNTL_POS;
|
||||
vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
@ -284,7 +94,6 @@ static void r300_update_vap_output_fmt(struct r300_context* r300,
|
|||
if (vs_outputs->psize != ATTR_UNUSED) {
|
||||
r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
|
||||
vs_outputs->psize);
|
||||
vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
|
||||
}
|
||||
|
||||
/* Colors. */
|
||||
|
@ -292,8 +101,6 @@ static void r300_update_vap_output_fmt(struct r300_context* r300,
|
|||
if (vs_outputs->color[i] != ATTR_UNUSED) {
|
||||
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
|
||||
vs_outputs->color[i]);
|
||||
vinfo->hwfmt[1] |= R300_INPUT_CNTL_COLOR;
|
||||
vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,8 +112,6 @@ static void r300_update_vap_output_fmt(struct r300_context* r300,
|
|||
if (vs_outputs->generic[i] != ATTR_UNUSED) {
|
||||
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
|
||||
vs_outputs->generic[i]);
|
||||
vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
|
||||
vinfo->hwfmt[3] |= (4 << (3 * gen_count));
|
||||
gen_count++;
|
||||
}
|
||||
}
|
||||
|
@ -315,15 +120,11 @@ static void r300_update_vap_output_fmt(struct r300_context* r300,
|
|||
if (vs_outputs->fog != ATTR_UNUSED) {
|
||||
r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
|
||||
vs_outputs->fog);
|
||||
vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
|
||||
vinfo->hwfmt[3] |= (4 << (3 * gen_count));
|
||||
gen_count++;
|
||||
}
|
||||
|
||||
/* XXX magic */
|
||||
assert(gen_count <= 8);
|
||||
|
||||
draw_compute_vertex_size(vinfo);
|
||||
}
|
||||
|
||||
/* Update the PSC tables. */
|
||||
|
@ -370,14 +171,14 @@ static void r300_vertex_psc(struct r300_context* r300)
|
|||
}
|
||||
|
||||
/* Update the PSC tables for SW TCL, using Draw. */
|
||||
static void r300_swtcl_vertex_psc(struct r300_context* r300,
|
||||
int* vs_output_tab)
|
||||
static void r300_swtcl_vertex_psc(struct r300_context* r300)
|
||||
{
|
||||
struct r300_vertex_info *vformat = r300->vertex_info;
|
||||
struct vertex_info* vinfo = &vformat->vinfo;
|
||||
uint16_t type, swizzle;
|
||||
enum pipe_format format;
|
||||
unsigned i, attrib_count;
|
||||
int* vs_output_tab = r300->vs->output_stream_loc_swtcl;
|
||||
|
||||
/* For each Draw attribute, route it to the fragment shader according
|
||||
* to the vs_output_tab. */
|
||||
|
@ -514,8 +315,8 @@ static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
|
|||
* of vertices into fragments. This is also the part of the chipset that
|
||||
* locks up if any part of it is even slightly wrong. */
|
||||
static void r300_update_rs_block(struct r300_context* r300,
|
||||
struct r300_shader_info* vs_outputs,
|
||||
struct r300_shader_info* fs_inputs)
|
||||
struct r300_shader_semantics* vs_outputs,
|
||||
struct r300_shader_semantics* fs_inputs)
|
||||
{
|
||||
struct r300_rs_block* rs = r300->rs_block;
|
||||
int i, col_count = 0, tex_count = 0, fp_offset = 0;
|
||||
|
@ -616,8 +417,6 @@ static void r300_update_rs_block(struct r300_context* r300,
|
|||
static void r300_update_derived_shader_state(struct r300_context* r300)
|
||||
{
|
||||
struct r300_screen* r300screen = r300_screen(r300->context.screen);
|
||||
struct r300_shader_info vs_outputs, fs_inputs;
|
||||
int vs_output_tab[16];
|
||||
|
||||
/*
|
||||
struct r300_shader_key* key;
|
||||
|
@ -648,18 +447,16 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
|
|||
/* Reset structures */
|
||||
memset(r300->rs_block, 0, sizeof(struct r300_rs_block));
|
||||
memset(r300->vertex_info, 0, sizeof(struct r300_vertex_info));
|
||||
memcpy(r300->vertex_info->vinfo.hwfmt, r300->vs->hwfmt, sizeof(uint)*4);
|
||||
|
||||
r300_shader_read_vs_outputs(&r300->vs->info, &vs_outputs);
|
||||
r300_shader_read_fs_inputs(&r300->fs->info, &fs_inputs);
|
||||
|
||||
r300_update_vap_output_fmt(r300, &vs_outputs);
|
||||
r300_update_rs_block(r300, &vs_outputs, &fs_inputs);
|
||||
r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs);
|
||||
|
||||
if (r300screen->caps->has_tcl) {
|
||||
r300_vertex_psc(r300);
|
||||
} else {
|
||||
r300_stream_locations_swtcl(&vs_outputs, vs_output_tab);
|
||||
r300_swtcl_vertex_psc(r300, vs_output_tab);
|
||||
r300_draw_emit_all_attribs(r300);
|
||||
draw_compute_vertex_size(&r300->vertex_info->vinfo);
|
||||
r300_swtcl_vertex_psc(r300);
|
||||
}
|
||||
|
||||
r300->dirty_state |= R300_NEW_RS_BLOCK;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
|
||||
* Copyright 2009 Marek Olšák <maraeo@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,13 +24,181 @@
|
|||
#include "r300_vs.h"
|
||||
|
||||
#include "r300_context.h"
|
||||
#include "r300_screen.h"
|
||||
#include "r300_tgsi_to_rc.h"
|
||||
#include "r300_reg.h"
|
||||
|
||||
#include "tgsi/tgsi_dump.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
#include "radeon_compiler.h"
|
||||
|
||||
/* Convert info about VS output semantics into r300_shader_semantics. */
|
||||
static void r300_shader_read_vs_outputs(
|
||||
struct tgsi_shader_info* info,
|
||||
struct r300_shader_semantics* vs_outputs)
|
||||
{
|
||||
int i;
|
||||
unsigned index;
|
||||
|
||||
r300_shader_semantics_reset(vs_outputs);
|
||||
|
||||
for (i = 0; i < info->num_outputs; i++) {
|
||||
index = info->output_semantic_index[i];
|
||||
|
||||
switch (info->output_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
assert(index == 0);
|
||||
vs_outputs->pos = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_PSIZE:
|
||||
assert(index == 0);
|
||||
vs_outputs->psize = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
assert(index <= ATTR_COLOR_COUNT);
|
||||
vs_outputs->color[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_BCOLOR:
|
||||
assert(index <= ATTR_COLOR_COUNT);
|
||||
vs_outputs->bcolor[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
assert(index <= ATTR_GENERIC_COUNT);
|
||||
vs_outputs->generic[index] = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
assert(index == 0);
|
||||
vs_outputs->fog = i;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void r300_shader_vap_output_fmt(
|
||||
struct r300_shader_semantics* vs_outputs,
|
||||
uint* hwfmt)
|
||||
{
|
||||
int i, gen_count;
|
||||
|
||||
/* Do the actual vertex_info setup.
|
||||
*
|
||||
* vertex_info has four uints of hardware-specific data in it.
|
||||
* vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
|
||||
* vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
|
||||
* vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
|
||||
* vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
|
||||
|
||||
hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
|
||||
|
||||
/* Position. */
|
||||
if (vs_outputs->pos != ATTR_UNUSED) {
|
||||
hwfmt[1] |= R300_INPUT_CNTL_POS;
|
||||
hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* Point size. */
|
||||
if (vs_outputs->psize != ATTR_UNUSED) {
|
||||
hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
|
||||
}
|
||||
|
||||
/* Colors. */
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
if (vs_outputs->color[i] != ATTR_UNUSED) {
|
||||
hwfmt[1] |= R300_INPUT_CNTL_COLOR;
|
||||
hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX Back-face colors. */
|
||||
|
||||
/* Texture coordinates. */
|
||||
gen_count = 0;
|
||||
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
|
||||
if (vs_outputs->generic[i] != ATTR_UNUSED) {
|
||||
hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
|
||||
hwfmt[3] |= (4 << (3 * gen_count));
|
||||
gen_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fog coordinates. */
|
||||
if (vs_outputs->fog != ATTR_UNUSED) {
|
||||
hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
|
||||
hwfmt[3] |= (4 << (3 * gen_count));
|
||||
gen_count++;
|
||||
}
|
||||
|
||||
/* XXX magic */
|
||||
assert(gen_count <= 8);
|
||||
}
|
||||
|
||||
/* Set VS output stream locations for SWTCL. */
|
||||
static void r300_stream_locations_swtcl(
|
||||
struct r300_shader_semantics* vs_outputs,
|
||||
int* output_stream_loc)
|
||||
{
|
||||
int i, tabi = 0, gen_count;
|
||||
|
||||
/* XXX Check whether the numbers (0, 1, 2+i, etc.) are correct.
|
||||
* These should go to VAP_PROG_STREAM_CNTL/DST_VEC_LOC. */
|
||||
|
||||
/* Position. */
|
||||
output_stream_loc[tabi++] = 0;
|
||||
|
||||
/* Point size. */
|
||||
if (vs_outputs->psize != ATTR_UNUSED) {
|
||||
output_stream_loc[tabi++] = 1;
|
||||
}
|
||||
|
||||
/* Colors. */
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
if (vs_outputs->color[i] != ATTR_UNUSED) {
|
||||
output_stream_loc[tabi++] = 2 + i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Back-face colors. */
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
|
||||
output_stream_loc[tabi++] = 4 + i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Texture coordinates. */
|
||||
gen_count = 0;
|
||||
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
|
||||
if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
|
||||
assert(tabi < 16);
|
||||
output_stream_loc[tabi++] = 6 + gen_count;
|
||||
gen_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fog coordinates. */
|
||||
if (vs_outputs->fog != ATTR_UNUSED) {
|
||||
assert(tabi < 16);
|
||||
output_stream_loc[tabi++] = 6 + gen_count;
|
||||
gen_count++;
|
||||
}
|
||||
|
||||
/* XXX magic */
|
||||
assert(gen_count <= 8);
|
||||
|
||||
for (; tabi < 16;) {
|
||||
output_stream_loc[tabi++] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
|
||||
{
|
||||
|
@ -99,20 +268,27 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
|
|||
default:
|
||||
debug_printf("r300: vs: Bad semantic declaration %d\n",
|
||||
decl->Semantic.SemanticName);
|
||||
break;
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
tgsi_parse_free(&parser);
|
||||
}
|
||||
|
||||
|
||||
void r300_translate_vertex_shader(struct r300_context* r300,
|
||||
struct r300_vertex_shader* vs)
|
||||
{
|
||||
struct r300_vertex_program_compiler compiler;
|
||||
struct tgsi_to_rc ttr;
|
||||
|
||||
/* Initialize. */
|
||||
r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
|
||||
r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt);
|
||||
|
||||
if (!r300_screen(r300->context.screen)->caps->has_tcl) {
|
||||
r300_stream_locations_swtcl(&vs->outputs, vs->output_stream_loc_swtcl);
|
||||
}
|
||||
|
||||
/* Setup the compiler */
|
||||
rc_init(&compiler.Base);
|
||||
|
||||
|
@ -137,7 +313,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
|
|||
/* Invoke the compiler */
|
||||
r3xx_compile_vertex_program(&compiler);
|
||||
if (compiler.Base.Error) {
|
||||
/* Todo: Fail gracefully */
|
||||
/* XXX Fail gracefully */
|
||||
fprintf(stderr, "r300 VP: Compiler error\n");
|
||||
abort();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
|
||||
* Copyright 2009 Marek Olšák <maraeo@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,15 +26,20 @@
|
|||
|
||||
#include "pipe/p_state.h"
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
|
||||
#include "radeon_code.h"
|
||||
|
||||
#include "r300_shader_semantics.h"
|
||||
|
||||
struct r300_context;
|
||||
|
||||
struct r300_vertex_shader {
|
||||
/* Parent class */
|
||||
struct pipe_shader_state state;
|
||||
|
||||
struct tgsi_shader_info info;
|
||||
struct r300_shader_semantics outputs;
|
||||
int output_stream_loc_swtcl[16];
|
||||
uint hwfmt[4];
|
||||
|
||||
/* Has this shader been translated yet? */
|
||||
boolean translated;
|
||||
|
@ -42,9 +48,6 @@ struct r300_vertex_shader {
|
|||
struct r300_vertex_program_code code;
|
||||
};
|
||||
|
||||
|
||||
extern struct r300_vertex_program_code r300_passthrough_vertex_shader;
|
||||
|
||||
void r300_translate_vertex_shader(struct r300_context* r300,
|
||||
struct r300_vertex_shader* vs);
|
||||
|
||||
|
|
Loading…
Reference in New Issue