mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 08:10:09 +01:00
r300g: split constant buffer and shader emittion
This commit is contained in:
parent
cab749a1d0
commit
2db46af875
5 changed files with 152 additions and 98 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue