ソースを参照

r300g: split constant buffer and shader emittion

tags/mesa_7_7_rc1
Maciej Cencora 16年前
コミット
2db46af875

+ 0
- 2
src/gallium/drivers/r300/r300_context.c ファイルの表示

@@ -22,8 +22,6 @@

#include "draw/draw_context.h"

#include "pipe/p_inlines.h"

#include "tgsi/tgsi_scan.h"

#include "util/u_hash_table.h"

+ 9
- 7
src/gallium/drivers/r300/r300_context.h ファイルの表示

@@ -26,6 +26,7 @@
#include "draw/draw_vertex.h"

#include "pipe/p_context.h"
#include "pipe/p_inlines.h"

struct r300_fragment_shader;
struct r300_vertex_shader;
@@ -119,10 +120,10 @@ struct r300_ztop_state {
#define R300_NEW_BLEND 0x00000001
#define R300_NEW_BLEND_COLOR 0x00000002
#define R300_NEW_CLIP 0x00000004
#define R300_NEW_CONSTANTS 0x00000008
#define R300_NEW_DSA 0x00000010
#define R300_NEW_FRAMEBUFFERS 0x00000020
#define R300_NEW_FRAGMENT_SHADER 0x00000040
#define R300_NEW_DSA 0x00000008
#define R300_NEW_FRAMEBUFFERS 0x00000010
#define R300_NEW_FRAGMENT_SHADER 0x00000020
#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040
#define R300_NEW_RASTERIZER 0x00000080
#define R300_NEW_RS_BLOCK 0x00000100
#define R300_NEW_SAMPLER 0x00000200
@@ -132,9 +133,10 @@ struct r300_ztop_state {
#define R300_ANY_NEW_TEXTURES 0x03fc0000
#define R300_NEW_VERTEX_FORMAT 0x04000000
#define R300_NEW_VERTEX_SHADER 0x08000000
#define R300_NEW_VIEWPORT 0x10000000
#define R300_NEW_QUERY 0x20000000
#define R300_NEW_KITCHEN_SINK 0x3fffffff
#define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000
#define R300_NEW_VIEWPORT 0x20000000
#define R300_NEW_QUERY 0x40000000
#define R300_NEW_KITCHEN_SINK 0x7fffffff

/* The next several objects are not pure Radeon state; they inherit from
* various Gallium classes. */

+ 101
- 56
src/gallium/drivers/r300/r300_emit.c ファイルの表示

@@ -178,18 +178,15 @@ static uint32_t pack_float24(float f)
}

void r300_emit_fragment_program_code(struct r300_context* r300,
struct rX00_fragment_program_code* generic_code,
struct r300_constant_buffer* externals)
struct rX00_fragment_program_code* generic_code)
{
struct r300_fragment_program_code * code = &generic_code->code.r300;
struct rc_constant_list * constants = &generic_code->constants;
int i;
CS_LOCALS(r300);

BEGIN_CS(15 +
code->alu.length * 4 +
(code->tex.length ? (1 + code->tex.length) : 0) +
(constants->Count ? (1 + constants->Count * 4) : 0));
(code->tex.length ? (1 + code->tex.length) : 0));

OUT_CS_REG(R300_US_CONFIG, code->config);
OUT_CS_REG(R300_US_PIXSIZE, code->pixsize);
@@ -221,32 +218,41 @@ void r300_emit_fragment_program_code(struct r300_context* r300,
OUT_CS(code->tex.inst[i]);
}

if (constants->Count) {
OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4);
for(i = 0; i < constants->Count; ++i) {
const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
OUT_CS(pack_float24(data[0]));
OUT_CS(pack_float24(data[1]));
OUT_CS(pack_float24(data[2]));
OUT_CS(pack_float24(data[3]));
}
}
END_CS;
}

void r300_emit_fs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants)
{
int i;
CS_LOCALS(r300);

if (constants->Count == 0)
return;

BEGIN_CS(constants->Count * 4 + 1);
OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4);
for(i = 0; i < constants->Count; ++i) {
const float * data = get_shader_constant(r300,
&constants->Constants[i],
&r300->shader_constants[PIPE_SHADER_FRAGMENT]);
OUT_CS(pack_float24(data[0]));
OUT_CS(pack_float24(data[1]));
OUT_CS(pack_float24(data[2]));
OUT_CS(pack_float24(data[3]));
}
END_CS;
}

void r500_emit_fragment_program_code(struct r300_context* r300,
struct rX00_fragment_program_code* generic_code,
struct r300_constant_buffer* externals)
struct rX00_fragment_program_code* generic_code)
{
struct r500_fragment_program_code * code = &generic_code->code.r500;
struct rc_constant_list * constants = &generic_code->constants;
int i;
CS_LOCALS(r300);

BEGIN_CS(13 +
((code->inst_end + 1) * 6) +
(constants->Count ? (3 + (constants->Count * 4)) : 0));
((code->inst_end + 1) * 6));
OUT_CS_REG(R500_US_CONFIG, 0);
OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
OUT_CS_REG(R500_US_CODE_RANGE,
@@ -266,18 +272,30 @@ void r500_emit_fragment_program_code(struct r300_context* r300,
OUT_CS(code->inst[i].inst5);
}

if (constants->Count) {
OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
for (i = 0; i < constants->Count; i++) {
const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
OUT_CS_32F(data[0]);
OUT_CS_32F(data[1]);
OUT_CS_32F(data[2]);
OUT_CS_32F(data[3]);
}
}
END_CS;
}
void r500_emit_fs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants)
{
int i;
CS_LOCALS(r300);
if (constants->Count == 0)
return;

BEGIN_CS(constants->Count * 4 + 2);
OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
for (i = 0; i < constants->Count; i++) {
const float * data = get_shader_constant(r300,
&constants->Constants[i],
&r300->shader_constants[PIPE_SHADER_FRAGMENT]);
OUT_CS_32F(data[0]);
OUT_CS_32F(data[1]);
OUT_CS_32F(data[2]);
OUT_CS_32F(data[3]);
}
END_CS;
}

@@ -621,8 +639,7 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
}

void r300_emit_vertex_program_code(struct r300_context* r300,
struct r300_vertex_program_code* code,
struct r300_constant_buffer* constants)
struct r300_vertex_program_code* code)
{
int i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
@@ -635,12 +652,7 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
return;
}

if (code->constants.Count) {
BEGIN_CS(14 + code->length + (code->constants.Count * 4));
} else {
BEGIN_CS(11 + code->length);
}

BEGIN_CS(11 + code->length);
/* R300_VAP_PVS_CODE_CNTL_0
* R300_VAP_PVS_CONST_CNTL
* R300_VAP_PVS_CODE_CNTL_1
@@ -658,20 +670,6 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
for (i = 0; i < code->length; i++)
OUT_CS(code->body.d[i]);

if (code->constants.Count) {
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
(r300screen->caps->is_r500 ?
R500_PVS_CONST_START : R300_PVS_CONST_START));
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4);
for (i = 0; i < code->constants.Count; i++) {
const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants);
OUT_CS_32F(data[0]);
OUT_CS_32F(data[1]);
OUT_CS_32F(data[2]);
OUT_CS_32F(data[3]);
}
}

OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) |
R300_PVS_NUM_CNTLRS(5) |
R300_PVS_NUM_FPUS(r300screen->caps->num_vert_fpus) |
@@ -683,7 +681,40 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
void r300_emit_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs)
{
r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]);
r300_emit_vertex_program_code(r300, &vs->code);
}

void r300_emit_vs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants)
{
int i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
CS_LOCALS(r300);

if (!r300screen->caps->has_tcl) {
debug_printf("r300: Implementation error: emit_vertex_shader called,"
" but has_tcl is FALSE!\n");
return;
}

if (constants->Count == 0)
return;

BEGIN_CS(constants->Count * 4 + 3);
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
(r300screen->caps->is_r500 ?
R500_PVS_CONST_START : R300_PVS_CONST_START));
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->Count * 4);
for (i = 0; i < constants->Count; i++) {
const float * data = get_shader_constant(r300,
&constants->Constants[i],
&r300->shader_constants[PIPE_SHADER_VERTEX]);
OUT_CS_32F(data[0]);
OUT_CS_32F(data[1]);
OUT_CS_32F(data[2]);
OUT_CS_32F(data[3]);
}
END_CS;
}

void r300_emit_viewport_state(struct r300_context* r300,
@@ -822,13 +853,22 @@ validate:

if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
if (r300screen->caps->is_r500) {
r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
r500_emit_fragment_program_code(r300, &r300->fs->code);
} else {
r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
r300_emit_fragment_program_code(r300, &r300->fs->code);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
}

if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
if (r300screen->caps->is_r500) {
r500_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
} else {
r300_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}

if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) {
r300_emit_fb_state(r300, &r300->framebuffer_state);
r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS;
@@ -887,6 +927,11 @@ validate:
r300->dirty_state &= ~R300_NEW_VERTEX_SHADER;
}

if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) {
r300_emit_vs_constant_buffer(r300, &r300->vs->code.constants);
r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
}

/* XXX
assert(r300->dirty_state == 0);
*/

+ 15
- 6
src/gallium/drivers/r300/r300_emit.h ファイルの表示

@@ -23,6 +23,9 @@
#ifndef R300_EMIT_H
#define R300_EMIT_H

#include "r300_context.h"
#include "radeon_code.h"

struct rX00_fragment_program_code;
struct r300_vertex_program_code;

@@ -39,12 +42,16 @@ void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa);

void r300_emit_fragment_program_code(struct r300_context* r300,
struct rX00_fragment_program_code* generic_code,
struct r300_constant_buffer* externals);
struct rX00_fragment_program_code* generic_code);

void r300_emit_fs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants);

void r500_emit_fragment_program_code(struct r300_context* r300,
struct rX00_fragment_program_code* generic_code,
struct r300_constant_buffer* externals);
struct rX00_fragment_program_code* generic_code);

void r500_emit_fs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants);

void r300_emit_fb_state(struct r300_context* r300,
struct pipe_framebuffer_state* fb);
@@ -72,8 +79,10 @@ void r300_emit_vertex_buffer(struct r300_context* r300);
void r300_emit_vertex_format_state(struct r300_context* r300);

void r300_emit_vertex_program_code(struct r300_context* r300,
struct r300_vertex_program_code* code,
struct r300_constant_buffer* constants);
struct r300_vertex_program_code* code);

void r300_emit_vs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants);

void r300_emit_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);

+ 27
- 27
src/gallium/drivers/r300/r300_state.c ファイルの表示

@@ -166,31 +166,6 @@ static void r300_set_clip_state(struct pipe_context* pipe,
}
}

static void
r300_set_constant_buffer(struct pipe_context* pipe,
uint shader, uint index,
const struct pipe_constant_buffer* buffer)
{
struct r300_context* r300 = r300_context(pipe);

/* This entire chunk of code seems ever-so-slightly baked.
* It's as if I've got pipe_buffer* matryoshkas... */
if (buffer && buffer->buffer && buffer->buffer->size) {
void* map = pipe->winsys->buffer_map(pipe->winsys, buffer->buffer,
PIPE_BUFFER_USAGE_CPU_READ);
memcpy(r300->shader_constants[shader].constants,
map, buffer->buffer->size);
pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer);

r300->shader_constants[shader].count =
buffer->buffer->size / (sizeof(float) * 4);
} else {
r300->shader_constants[shader].count = 0;
}

r300->dirty_state |= R300_NEW_CONSTANTS;
}

/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
*
* This contains the depth buffer, stencil buffer, alpha test, and such.
@@ -345,7 +320,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)

r300->fs = fs;

r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}

/* Delete fragment shader state. */
@@ -702,7 +677,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)

draw_bind_vertex_shader(r300->draw, vs->draw);
r300->vs = vs;
r300->dirty_state |= R300_NEW_VERTEX_SHADER;
r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
} else {
draw_bind_vertex_shader(r300->draw,
(struct draw_vertex_shader*)shader);
@@ -726,6 +701,31 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
}
}

static void r300_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
const struct pipe_constant_buffer *buf)
{
struct r300_context* r300 = r300_context(pipe);
void *mapped;

if (buf == NULL || buf->buffer->size == 0 ||
(mapped = pipe_buffer_map(pipe->screen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)) == NULL)
{
r300->shader_constants[shader].count = 0;
return;
}

assert((buf->buffer->size % 4 * sizeof(float)) == 0);
memcpy(r300->shader_constants[shader].constants, mapped, buf->buffer->size);
r300->shader_constants[shader].count = buf->buffer->size / (4 * sizeof(float));
pipe_buffer_unmap(pipe->screen, buf->buffer);

if (shader == PIPE_SHADER_VERTEX)
r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
else if (shader == PIPE_SHADER_FRAGMENT)
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}

void r300_init_state_functions(struct r300_context* r300)
{
r300->context.create_blend_state = r300_create_blend_state;

読み込み中…
キャンセル
保存