#include "util/u_helpers.h"
#include "util/u_math.h"
#include "util/u_pack_color.h"
+#include "util/u_upload_mgr.h"
+#include "util/u_format_s3tc.h"
#include "tgsi/tgsi_parse.h"
#include "radeonsi_pipe.h"
#include "radeonsi_shader.h"
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
+ struct pipe_constant_buffer cb;
if (pm4 == NULL)
return;
fui(state->ucp[i][3]));
}
+ cb.buffer = NULL;
+ cb.user_buffer = state->ucp;
+ cb.buffer_offset = 0;
+ cb.buffer_size = 4*4*8;
+ ctx->set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
+
si_pm4_set_state(rctx, clip, pm4);
}
-static void si_set_scissor_state(struct pipe_context *ctx,
- const struct pipe_scissor_state *state)
+static void si_set_scissor_states(struct pipe_context *ctx,
+ unsigned start_slot,
+ unsigned num_scissors,
+ const struct pipe_scissor_state *state)
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
si_pm4_set_state(rctx, scissor, pm4);
}
-static void si_set_viewport_state(struct pipe_context *ctx,
- const struct pipe_viewport_state *state)
+static void si_set_viewport_states(struct pipe_context *ctx,
+ unsigned start_slot,
+ unsigned num_viewports,
+ const struct pipe_viewport_state *state)
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct si_state_viewport *viewport = CALLOC_STRUCT(si_state_viewport);
}
rs->two_side = state->light_twoside;
+ rs->clip_plane_enable = state->clip_plane_enable;
polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
state->fill_back != PIPE_POLYGON_MODE_FILL);
S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
- rs->pa_cl_vs_out_cntl =
- S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) |
- S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex);
clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
si_pm4_set_reg(pm4, R_028BDC_PA_SC_LINE_CNTL, 0x00000400);
si_pm4_set_reg(pm4, R_028BE4_PA_SU_VTX_CNTL,
- S_028BE4_PIX_CENTER(state->gl_rasterization_rules));
+ S_028BE4_PIX_CENTER(state->half_pixel_center));
si_pm4_set_reg(pm4, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000);
si_pm4_set_reg(pm4, R_028BEC_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000);
si_pm4_set_reg(pm4, R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000);
rctx->sprite_coord_enable = rs->sprite_coord_enable;
rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
rctx->pa_su_sc_mode_cntl = rs->pa_su_sc_mode_cntl;
- rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
- rctx->pa_cl_vs_out_cntl = rs->pa_cl_vs_out_cntl;
si_pm4_bind_state(rctx, rasterizer, rs);
si_update_fb_rs_state(rctx);
const struct util_format_description *desc,
int first_non_void)
{
+ struct r600_screen *rscreen = (struct r600_screen*)screen;
+ bool enable_s3tc = rscreen->info.drm_minor >= 31;
boolean uniform = TRUE;
int i;
break;
}
- /* TODO compressed formats */
+ if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
+ if (!enable_s3tc)
+ goto out_unknown;
+
+ switch (format) {
+ case PIPE_FORMAT_RGTC1_SNORM:
+ case PIPE_FORMAT_LATC1_SNORM:
+ case PIPE_FORMAT_RGTC1_UNORM:
+ case PIPE_FORMAT_LATC1_UNORM:
+ return V_008F14_IMG_DATA_FORMAT_BC4;
+ case PIPE_FORMAT_RGTC2_SNORM:
+ case PIPE_FORMAT_LATC2_SNORM:
+ case PIPE_FORMAT_RGTC2_UNORM:
+ case PIPE_FORMAT_LATC2_UNORM:
+ return V_008F14_IMG_DATA_FORMAT_BC5;
+ default:
+ goto out_unknown;
+ }
+ }
+
+ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+
+ if (!enable_s3tc)
+ goto out_unknown;
+
+ if (!util_format_s3tc_enabled) {
+ goto out_unknown;
+ }
+
+ switch (format) {
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT1_SRGB:
+ case PIPE_FORMAT_DXT1_SRGBA:
+ return V_008F14_IMG_DATA_FORMAT_BC1;
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT3_SRGBA:
+ return V_008F14_IMG_DATA_FORMAT_BC2;
+ case PIPE_FORMAT_DXT5_RGBA:
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return V_008F14_IMG_DATA_FORMAT_BC3;
+ default:
+ goto out_unknown;
+ }
+ }
if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
return V_008F14_IMG_DATA_FORMAT_5_9_9_9;
si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info);
si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib);
+ /* set CB_COLOR1_INFO for possible dual-src blending */
+ if (state->nr_cbufs == 1) {
+ assert(cb == 0);
+ si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + 1 * 0x3C, color_info);
+ }
+
/* Determine pixel shader export format */
max_comp_size = si_colorformat_max_comp_size(format);
if (ntype == V_028C70_NUMBER_SRGB ||
max_comp_size <= 10) ||
(ntype == V_028C70_NUMBER_FLOAT && max_comp_size <= 16)) {
rctx->export_16bpc |= 1 << cb;
+ /* set SPI_SHADER_COL_FORMAT for possible dual-src blending */
+ if (state->nr_cbufs == 1)
+ rctx->export_16bpc |= 1 << 1;
}
}
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
- uint32_t shader_mask, tl, br;
+ uint32_t tl, br;
int tl_x, tl_y, br_x, br_y;
if (pm4 == NULL)
assert(!(rctx->export_16bpc & ~0xff));
si_db(rctx, pm4, state);
- shader_mask = 0;
- for (int i = 0; i < state->nr_cbufs; i++) {
- shader_mask |= 0xf << (i * 4);
- }
tl_x = 0;
tl_y = 0;
br_x = state->width;
si_pm4_set_reg(pm4, R_028208_PA_SC_WINDOW_SCISSOR_BR, br);
si_pm4_set_reg(pm4, R_028200_PA_SC_WINDOW_OFFSET, 0x00000000);
si_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA);
- si_pm4_set_reg(pm4, R_02823C_CB_SHADER_MASK, shader_mask);
si_pm4_set_reg(pm4, R_028BE0_PA_SC_AA_CONFIG, 0x00000000);
si_pm4_set_state(rctx, framebuffer, pm4);
break;
default:
if (first_non_void < 0) {
- num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
+ if (util_format_is_compressed(pipe_format)) {
+ switch (pipe_format) {
+ case PIPE_FORMAT_DXT1_SRGB:
+ case PIPE_FORMAT_DXT1_SRGBA:
+ case PIPE_FORMAT_DXT3_SRGBA:
+ case PIPE_FORMAT_DXT5_SRGBA:
+ num_format = V_008F14_IMG_NUM_FORMAT_SRGB;
+ break;
+ case PIPE_FORMAT_RGTC1_SNORM:
+ case PIPE_FORMAT_LATC1_SNORM:
+ case PIPE_FORMAT_RGTC2_SNORM:
+ case PIPE_FORMAT_LATC2_SNORM:
+ num_format = V_008F14_IMG_NUM_FORMAT_SNORM;
+ break;
+ default:
+ num_format = V_008F14_IMG_NUM_FORMAT_UNORM;
+ break;
+ }
+ } else {
+ num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
+ }
} else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
num_format = V_008F14_IMG_NUM_FORMAT_SRGB;
} else {
FREE(resource);
}
+static bool wrap_mode_uses_border_color(unsigned wrap, bool linear_filter)
+{
+ return wrap == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
+ wrap == PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER ||
+ (linear_filter &&
+ (wrap == PIPE_TEX_WRAP_CLAMP ||
+ wrap == PIPE_TEX_WRAP_MIRROR_CLAMP));
+}
+
+static bool sampler_state_needs_border_color(const struct pipe_sampler_state *state)
+{
+ bool linear_filter = state->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
+ state->mag_img_filter != PIPE_TEX_FILTER_NEAREST;
+
+ return (state->border_color.ui[0] || state->border_color.ui[1] ||
+ state->border_color.ui[2] || state->border_color.ui[3]) &&
+ (wrap_mode_uses_border_color(state->wrap_s, linear_filter) ||
+ wrap_mode_uses_border_color(state->wrap_t, linear_filter) ||
+ wrap_mode_uses_border_color(state->wrap_r, linear_filter));
+}
+
static void *si_create_sampler_state(struct pipe_context *ctx,
const struct pipe_sampler_state *state)
{
struct si_pipe_sampler_state *rstate = CALLOC_STRUCT(si_pipe_sampler_state);
- union util_color uc;
unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 2 : 0;
unsigned border_color_type;
return NULL;
}
- util_pack_color(state->border_color.f, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
- switch (uc.ui) {
- case 0x000000FF:
- border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK;
- break;
- case 0x00000000:
- border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
- break;
- case 0xFFFFFFFF:
- border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE;
- break;
- default: /* Use border color pointer */
+ if (sampler_state_needs_border_color(state))
border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER;
- }
+ else
+ border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
rstate->val[0] = (S_008F30_CLAMP_X(si_tex_wrap(state->wrap_s)) |
S_008F30_CLAMP_Y(si_tex_wrap(state->wrap_t)) |
rstate->val[3] = S_008F3C_BORDER_COLOR_TYPE(border_color_type);
if (border_color_type == V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER) {
- memcpy(rstate->border_color, state->border_color.f,
+ memcpy(rstate->border_color, state->border_color.ui,
sizeof(rstate->border_color));
}
}
for (j = 0; j < 4; j++) {
- union fi border_color;
-
- border_color.f = rstates[i]->border_color[j];
border_color_table[4 * rctx->border_color_offset + j] =
- util_le32_to_cpu(border_color.i);
+ util_le32_to_cpu(rstates[i]->border_color[j]);
}
rstates[i]->val[3] &= C_008F3C_BORDER_COLOR_PTR;
(void*)rctx->border_color_table);
si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, va_offset >> 8);
+ if (rctx->chip_class >= CIK)
+ si_pm4_set_reg(pm4, R_028084_TA_BC_BASE_ADDR_HI, va_offset >> 40);
rctx->ws->buffer_unmap(rctx->border_color_table->cs_buf);
si_pm4_add_bo(pm4, rctx->border_color_table, RADEON_USAGE_READ);
}
* Constants
*/
static void si_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
- struct pipe_constant_buffer *cb)
+ struct pipe_constant_buffer *input)
{
struct r600_context *rctx = (struct r600_context *)ctx;
- struct si_resource *rbuffer = cb ? si_resource(cb->buffer) : NULL;
- struct si_pm4_state *pm4;
- uint32_t offset;
- uint64_t va;
+ struct r600_constbuf_state *state = &rctx->constbuf_state[shader];
+ struct pipe_constant_buffer *cb;
+ const uint8_t *ptr;
/* Note that the state tracker can unbind constant buffers by
* passing NULL here.
*/
- if (cb == NULL || (!cb->buffer && !cb->user_buffer))
+ if (unlikely(!input || (!input->buffer && !input->user_buffer))) {
+ state->enabled_mask &= ~(1 << index);
+ state->dirty_mask &= ~(1 << index);
+ pipe_resource_reference(&state->cb[index].buffer, NULL);
return;
+ }
- pm4 = CALLOC_STRUCT(si_pm4_state);
- si_pm4_inval_shader_cache(pm4);
-
- if (cb->user_buffer)
- r600_upload_const_buffer(rctx, &rbuffer, cb->user_buffer, cb->buffer_size, &offset);
- else
- offset = 0;
- va = r600_resource_va(ctx->screen, (void*)rbuffer);
- va += offset;
-
- si_pm4_add_bo(pm4, rbuffer, RADEON_USAGE_READ);
-
- si_pm4_sh_data_begin(pm4);
-
- /* Fill in a T# buffer resource description */
- si_pm4_sh_data_add(pm4, va);
- si_pm4_sh_data_add(pm4, (S_008F04_BASE_ADDRESS_HI(va >> 32) |
- S_008F04_STRIDE(0)));
- si_pm4_sh_data_add(pm4, cb->buffer_size);
- si_pm4_sh_data_add(pm4, S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
- S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
- S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
- S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
- S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
- S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32));
-
- switch (shader) {
- case PIPE_SHADER_VERTEX:
- si_pm4_sh_data_end(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0, SI_SGPR_CONST);
- si_pm4_set_state(rctx, vs_const, pm4);
- break;
+ cb = &state->cb[index];
+ cb->buffer_size = input->buffer_size;
- case PIPE_SHADER_FRAGMENT:
- si_pm4_sh_data_end(pm4, R_00B030_SPI_SHADER_USER_DATA_PS_0, SI_SGPR_CONST);
- si_pm4_set_state(rctx, ps_const, pm4);
- break;
+ ptr = input->user_buffer;
- default:
- R600_ERR("unsupported %d\n", shader);
- FREE(pm4);
+ if (ptr) {
+ r600_upload_const_buffer(rctx,
+ (struct si_resource**)&cb->buffer, ptr,
+ cb->buffer_size, &cb->buffer_offset);
+ } else {
+ /* Setup the hw buffer. */
+ cb->buffer_offset = input->buffer_offset;
+ pipe_resource_reference(&cb->buffer, input->buffer);
}
- if (cb->buffer != &rbuffer->b.b)
- si_resource_reference(&rbuffer, NULL);
+ state->enabled_mask |= 1 << index;
+ state->dirty_mask |= 1 << index;
}
/*
rctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(rctx, false, false);
rctx->context.set_clip_state = si_set_clip_state;
- rctx->context.set_scissor_state = si_set_scissor_state;
- rctx->context.set_viewport_state = si_set_viewport_state;
+ rctx->context.set_scissor_states = si_set_scissor_states;
+ rctx->context.set_viewport_states = si_set_viewport_states;
rctx->context.set_stencil_ref = si_set_pipe_stencil_ref;
rctx->context.set_framebuffer_state = si_set_framebuffer_state;
case CHIP_OLAND:
si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000082);
break;
+ case CHIP_HAINAN:
+ si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000000);
+ break;
default:
si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000000);
break;